Stack trace
Three worker goroutines panic identically per run; first one below (from typescript@7.1.0-dev.20260726.1; typescript@7.0.2 produces the same frames at the same lines):
panic: runtime error: invalid memory address or nil pointer dereference [recovered, repanicked]
[signal SIGSEGV: segmentation violation code=0x2 addr=0xc pc=0x1045fcf98]
goroutine 39500 [running]:
sync.(*WaitGroup).Go.func1.1()
sync/waitgroup.go:251 +0x48
panic({0x1055aae20?, 0x1058a0e60?})
runtime/panic.go:860 +0x12c
github.com/microsoft/typescript-go/internal/ast.(*Node).End(...)
github.com/microsoft/typescript-go/internal/ast/ast.go:194
github.com/microsoft/typescript-go/internal/ast.(*NodeList).HasTrailingComma(...)
github.com/microsoft/typescript-go/internal/ast/ast.go:143
github.com/microsoft/typescript-go/internal/printer.(*Printer).hasTrailingComma(0x23bcc53aadc0?, 0x104c19f78?, 0x23bd0871dae8?)
github.com/microsoft/typescript-go/internal/printer/printer.go:4774 +0x28
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitListRange(0x23bd2c208700, 0x105802028, 0x23bd0741f760, 0x23bd0750cd48, 0xd210, 0x10430f7ec?, 0x20?)
github.com/microsoft/typescript-go/internal/printer/printer.go:4755 +0x2bc
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitList(0x23bd2c208700, 0x105802028, 0x23bd0741f760, 0x23bd0750cd48, 0xd210)
github.com/microsoft/typescript-go/internal/printer/printer.go:4700 +0x94
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitTypeParameters(0x1055c6000?, 0x23bd07542c60?, 0x23bd0741f760?)
github.com/microsoft/typescript-go/internal/printer/printer.go:1506 +0x4c
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitFunctionType(0x23bd2c208700, 0x23bd0741f760)
github.com/microsoft/typescript-go/internal/printer/printer.go:1928 +0x15c
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitTypeNode(0x23bd2c208700, 0x23bd0741f760, 0x871dcb8?)
github.com/microsoft/typescript-go/internal/printer/printer.go:2309 +0x20c
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitTypeNodePreservingExtends(...)
github.com/microsoft/typescript-go/internal/printer/printer.go:2271
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitTypeNodeOutsideExtends(...)
github.com/microsoft/typescript-go/internal/printer/printer.go:2265
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitTypeAnnotation(0x23bd2c208700, 0x23bd0741f760)
github.com/microsoft/typescript-go/internal/printer/printer.go:1516 +0x84
github.com/microsoft/typescript-go/internal/printer.(*Printer).emitPropertySignature(0x23bd2c208700, 0x23bd08134428)
github.com/microsoft/typescript-go/internal/printer/printer.go:1647 +0x78
Further up the same stacks: emitImportTypeNode (several frames) and printer.(*Printer).Write, i.e. build-mode declaration-text printing. Full 3-goroutine dump available on request.
This looks like the same underlying failure as microsoft/typescript-go#3467 (identical bottom frames ast.(*Node).End → NodeList.HasTrailingComma → printer.hasTrailingComma → emitListRange), which was hit through the LSP hover path and is closed — this report is the build-mode / incremental path, and it still reproduces on the current nightly.
Steps to reproduce
Reproduces 100% deterministically (5/5 runs) on our project, but only via the incremental path:
tsc --noEmit on a clean tree (writes tsconfig.tsbuildinfo) → exits 0.
- Apply a small refactor. Five different minimal edits all trigger it; the simplest is renaming a generic setter action on one mobx-state-tree store —
updateField<Key extends keyof typeof self>(key, value) → onChangeField (16 changed lines across 3 files; the same method name already exists on a sibling store type, and a view elsewhere returns the union of the two store instance types).
tsc --noEmit again → panic above.
Notes:
- Deleting
tsconfig.tsbuildinfo between steps 2 and 3 makes the run pass — cold full checks never crash; only the rebuild that reuses build info does.
--singleThreaded crashes identically, so it is not a concurrency race.
- Version matrix on the identical tree + edit:
typescript@7.0.2 crash, typescript@7.1.0-dev.20260726.1 crash (recipe re-run natively with the nightly, including rebuilding the buildinfo with it); @typescript/typescript6@6.0.2 clean, typescript@5.9.2 clean (same 15 pre-existing unrelated TS7006 diagnostics before and after the edit, so the edit is type-correct).
- Besides the rename, four other small edits reproduced the same panic on this codebase over the past days: deleting an unused model property + the views reading it; adding a co-located
interface X extends Instance<typeof Model> into a model's own file; swapping a types.compose member from a locally-declared model to an imported one; using a shared type-guard for narrowing inside another model's action.
- Environment: macOS arm64 (Darwin 25.5.0), Node v24.14.0, pnpm. Project: Vite + React app, ~2k modules,
mobx-state-tree@7.3.1. Relevant compilerOptions: strict, noEmit: true, incremental: true, moduleResolution: "bundler", verbatimModuleSyntax, isolatedModules, skipLibCheck, target/module: ESNext.
The codebase is private, so I can't attach it. I tried to minimize (two MST roots with the same-named generic keyof typeof self setter, a view returning the union of both instance types, 60-field models, same incremental+rename recipe) — the synthetic project does not crash, so the trigger seems to need the real project's type complexity. Happy to bisect, run instrumented/debug builds, or capture whatever extra diagnostics would help against the real repo.
Stack trace
Three worker goroutines panic identically per run; first one below (from
typescript@7.1.0-dev.20260726.1;typescript@7.0.2produces the same frames at the same lines):Further up the same stacks:
emitImportTypeNode(several frames) andprinter.(*Printer).Write, i.e. build-mode declaration-text printing. Full 3-goroutine dump available on request.This looks like the same underlying failure as microsoft/typescript-go#3467 (identical bottom frames
ast.(*Node).End→NodeList.HasTrailingComma→printer.hasTrailingComma→emitListRange), which was hit through the LSP hover path and is closed — this report is the build-mode / incremental path, and it still reproduces on the current nightly.Steps to reproduce
Reproduces 100% deterministically (5/5 runs) on our project, but only via the incremental path:
tsc --noEmiton a clean tree (writestsconfig.tsbuildinfo) → exits 0.updateField<Key extends keyof typeof self>(key, value)→onChangeField(16 changed lines across 3 files; the same method name already exists on a sibling store type, and a view elsewhere returns the union of the two store instance types).tsc --noEmitagain → panic above.Notes:
tsconfig.tsbuildinfobetween steps 2 and 3 makes the run pass — cold full checks never crash; only the rebuild that reuses build info does.--singleThreadedcrashes identically, so it is not a concurrency race.typescript@7.0.2crash,typescript@7.1.0-dev.20260726.1crash (recipe re-run natively with the nightly, including rebuilding the buildinfo with it);@typescript/typescript6@6.0.2clean,typescript@5.9.2clean (same 15 pre-existing unrelatedTS7006diagnostics before and after the edit, so the edit is type-correct).interface X extends Instance<typeof Model>into a model's own file; swapping atypes.composemember from a locally-declared model to an imported one; using a shared type-guard for narrowing inside another model's action.mobx-state-tree@7.3.1. RelevantcompilerOptions:strict,noEmit: true,incremental: true,moduleResolution: "bundler",verbatimModuleSyntax,isolatedModules,skipLibCheck,target/module: ESNext.The codebase is private, so I can't attach it. I tried to minimize (two MST roots with the same-named generic
keyof typeof selfsetter, a view returning the union of both instance types, 60-field models, same incremental+rename recipe) — the synthetic project does not crash, so the trigger seems to need the real project's type complexity. Happy to bisect, run instrumented/debug builds, or capture whatever extra diagnostics would help against the real repo.