Skip to content

[finding] The parse-error blind spot is wider than scripts/ts-parse.mjs closed — ts.createProgram, ts.transpileModule, and 10 sites in packages/ #10575

Description

@claude

Filed while implementing #10133. Nothing is red today — same framing as the parent card, and for the same reason.

#10133 closed one parser (ts.createSourceFile) in one tree (scripts/**). The class is wider on both axes, measured on main at 68ca346:

Axis 1 — two other TypeScript parse entry points, both inside scripts/**

Neither is covered by scripts/ts-parse.mjs, and both are named in check-parse-guard.mjs's header as deliberately not covered so its green line does not over-claim:

  • scripts/check-published-readme-exports.mjs:775ts.createProgram([...absEntries], TS_OPTIONS). A Program reports syntax through getSyntacticDiagnostics(), a different API. Nothing reads it.
  • scripts/check-where-matcher-conformance.mjs:481ts.transpileModule(code, { ... }). It reports nothing at all unless reportDiagnostics: true is passed, so it is the quietest of the three.

Axis 2 — every parse outside scripts/**

These cannot import the root scripts/ts-parse.mjs for the reason invoked-as.mjs gives about its own packages/cli sibling: scripts/ runs as plain .mjs against a possibly unbuilt tree, and making a published package depend on repo tooling to answer "did this parse?" trades one bug for a worse one. So this needs a decision about shape, not a copy of the helper.

filesitesnote
packages/lint/src/validate-react-page-props.ts1wrapped in try { ... } catch { continue; }
packages/lint/src/lint-startup-registry-verdict.ts1wrapped in try { ... } catch { return []; }
packages/lint/src/validate-hook-body-writes.ts1also the only site anywhere passing setParentNodes: false
packages/lint/scripts/check-doc-formula-expressions.mjs3a gate
packages/spec/scripts/check-skill-examples.ts2a gate (one of the pure source audits)
packages/spec/scripts/lib/strictness-ledger.ts1generator/gate library
packages/cli/src/utils/detect-free-identifiers.ts1runtime, not a gate

The two try/catch wrappers are worth naming separately. They are dead code today — createSourceFile cannot throw — but they are written as continue / return [], so the moment a parse did throw they would become a silent skip rather than a loud failure. That is the same defect this class is about, pre-installed. validate-react-page-props.ts's own comment says "the syntax gate reports unparseable sources", which is a claim worth verifying rather than inheriting.

What this is not

Not a request to copy ts-parse.mjs into packages/. The decision a card here has to make is whether the package-side lint validators want the same refusal semantics at all: scripts/** gates audit a tree the author controls, while a publish-time lint validator is handed metadata by an author and may legitimately want to report an unparseable source rather than abort the process. Those are different contracts and the answer may differ per row above.

Refs: #10133 (the parent class, scripts/** half) · #10573 (the implementation and its measurements)


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions