🔎 Search Terms
incremental json stale diagnostics, resolveJsonModule incremental, tsbuildinfo stale error json, semanticDiagnosticsPerFile json, incremental diagnostics not cleared
🕗 Version & Regression Information
- Broken in:
typescript@7.0.2 (tsc -p . with "incremental": true)
- Still broken in nightly:
typescript@7.1.0-dev.20260825.1 (identical repro output)
- Works in:
typescript@5.9.3 — the identical file cycle clears the error correctly
- Not expressible in the Playground (requires
--incremental state across multiple compilations)
💻 Code
Three files:
tsconfig.json
{
"compilerOptions": {
"strict": true,
"noEmit": true,
"incremental": true,
"resolveJsonModule": true,
"esModuleInterop": true
}
}
data.json
check.ts
import type data from "./data.json";
type Shape = { title: string };
type Covers<T extends Shape> = T;
export type Check = Covers<typeof data>;
Repro steps:
rm -f tsconfig.tsbuildinfo
printf '{ "title": "hello" }\n' > data.json
tsc -p . # 1. cold run: clean ✅
printf '{ }\n' > data.json
tsc -p . # 2. warm run: TS2741 — correct ✅
printf '{ "title": "fixed" }\n' > data.json
tsc -p . # 3. warm run: STILL TS2741 ❌ — data.json on disk has "title"
rm -f tsconfig.tsbuildinfo
tsc -p . # 4. identical files, cache deleted: clean ✅
🙁 Actual behavior
Step 3 keeps failing on every subsequent run:
check.ts(6,28): error TS2741: Property 'title' is missing in type '{}' but required in type 'Shape'.
The diagnostic describes content that no longer exists ('{}' — the file contains "title": "fixed"). No edit to the JSON file ever clears it — neither new valid content nor restoring the original bytes. Only deleting tsconfig.tsbuildinfo (or turning off incremental) recovers. Note the asymmetry: the JSON change that introduces the error (step 2) is detected on a warm run; only clearing is broken.
Diffing tsconfig.tsbuildinfo between steps 2 and 3 shows the mechanism: the only change is data.json's content-hash version in fileInfos — so the changed JSON was registered — but the semanticDiagnosticsPerFile entry for check.ts still holds the old TS2741 ("messageArgs": ["title", "{}", "Shape"]) and is replayed instead of the file being re-checked.
The same behavior reproduces with a value import (import data from "./data.json"), with "moduleResolution": "bundler", and in a large real project (Next.js app where locale JSON catalogs are type-checked against en.json — fixing the catalog after a failing check strands the build red until the buildinfo is deleted).
🙂 Expected behavior
Step 3 exits clean, as typescript@5.9.3 does for the identical sequence: fixing the JSON module re-checks its dependents and clears the cached diagnostics.
Additional information
Related but distinct: microsoft/typescript-go#2666 covers missing invalidation for changed external dependencies; this report is in-project JSON modules, where the changed file's hash is visibly updated in the buildinfo yet dependents' cached diagnostics are not invalidated.
Disclosure: this issue was investigated and written by Claude (Anthropic's AI assistant), working in Claude Code on behalf of the reporter. The repro and the 5.9.3/7.0.2 comparison were executed and verified, not inferred.
🔎 Search Terms
incremental json stale diagnostics, resolveJsonModule incremental, tsbuildinfo stale error json, semanticDiagnosticsPerFile json, incremental diagnostics not cleared
🕗 Version & Regression Information
typescript@7.0.2(tsc -p .with"incremental": true)typescript@7.1.0-dev.20260825.1(identical repro output)typescript@5.9.3— the identical file cycle clears the error correctly--incrementalstate across multiple compilations)💻 Code
Three files:
tsconfig.json{ "compilerOptions": { "strict": true, "noEmit": true, "incremental": true, "resolveJsonModule": true, "esModuleInterop": true } }data.json{ "title": "hello" }check.tsRepro steps:
🙁 Actual behavior
Step 3 keeps failing on every subsequent run:
The diagnostic describes content that no longer exists (
'{}'— the file contains"title": "fixed"). No edit to the JSON file ever clears it — neither new valid content nor restoring the original bytes. Only deletingtsconfig.tsbuildinfo(or turning offincremental) recovers. Note the asymmetry: the JSON change that introduces the error (step 2) is detected on a warm run; only clearing is broken.Diffing
tsconfig.tsbuildinfobetween steps 2 and 3 shows the mechanism: the only change isdata.json's content-hashversioninfileInfos— so the changed JSON was registered — but thesemanticDiagnosticsPerFileentry forcheck.tsstill holds the oldTS2741("messageArgs": ["title", "{}", "Shape"]) and is replayed instead of the file being re-checked.The same behavior reproduces with a value import (
import data from "./data.json"), with"moduleResolution": "bundler", and in a large real project (Next.js app where locale JSON catalogs are type-checked againsten.json— fixing the catalog after a failing check strands the build red until the buildinfo is deleted).🙂 Expected behavior
Step 3 exits clean, as
typescript@5.9.3does for the identical sequence: fixing the JSON module re-checks its dependents and clears the cached diagnostics.Additional information
Related but distinct: microsoft/typescript-go#2666 covers missing invalidation for changed external dependencies; this report is in-project JSON modules, where the changed file's hash is visibly updated in the buildinfo yet dependents' cached diagnostics are not invalidated.
Disclosure: this issue was investigated and written by Claude (Anthropic's AI assistant), working in Claude Code on behalf of the reporter. The repro and the 5.9.3/7.0.2 comparison were executed and verified, not inferred.