Skip to content

[api-extractor] Source map segment without a source crashes SourceMapper with "Target is a folder, not a file" #6156

Open

Description

@joshuaellis

Summary

API Extractor crashes when a .d.ts.map contains a mapping segment that has only a generated column and no source. The source map spec allows these segments, and rolldown 1.2.14 now emits them in declaration maps (rolldown/rolldown#11170). We hit this upgrading rolldown in sanity-io/sdk#1445.

Repro steps

  1. Create these files:

package.json

{"name":"ae-repro","version":"1.0.0","types":"dist/index.d.ts"}

src/index.ts

export const foo: string = "foo"

dist/index.d.ts

export declare const foo: string

dist/index.d.ts.map (the second segment, qB, has one field: a generated column with no source)

{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":"AAAA,qB"}

api-extractor.json

{
  "projectFolder": ".",
  "mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts",
  "apiReport": {"enabled": true, "reportFolder": "<projectFolder>/etc/"},
  "docModel": {"enabled": false},
  "dtsRollup": {"enabled": false},
  "compiler": {"overrideTsconfig": {"compilerOptions": {"strict": true}}}
}
  1. mkdir etc && npx @microsoft/api-extractor@7.59.4 run --local

Expected result: The run completes and reports ae-missing-release-tag for foo. It does when the mappings are AAAA,qBAAqB.

Actual result:

ERROR: Target is a folder, not a file: undefined
Target is a folder, not a file: undefined
EISDIR: illegal operation on a directory, read
    at Object.readFileSync (node:fs)
    at FileSystem.readFile (@rushstack/node-core-library/src/FileSystem.ts:1066:12)
    at SourceMapper.#getMappedSourceLocation (@microsoft/api-extractor/src/collector/SourceMapper.ts:130:56)

Details

SourceMapper.#getMappedSourceLocation takes the nearest mapping item and runs path.resolve(path.dirname(sourceFilePath), nearestMappingItem.source). For a source-less segment source is empty, so the path resolves to the .d.ts file's folder. FileSystem.exists returns true for it, and the read fails.

Treating a mapping item with no source as "no mapping" would fix it, so the original .d.ts location is used.

Standard questions

Question Answer
@microsoft/api-extractor version? 7.59.4
Operating system? Mac (also Linux in GitHub Actions)
API Extractor scenario? reporting (.api.md)
Would you consider contributing a PR? No
TypeScript compiler version? 5.9.3 (bundled); also 6.0.3 in our project
Node.js version (node -v)? 24.12.0 (also 22 in CI)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Needs triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions