microsoft / microsoft/TypeScript

Panic: nil pointer in NodeList.HasTrailingComma during incremental rebuild (build-mode declaration printer) — 7.0.2 and current nightly

Open
#63,865 4 comments 0 reactions 1 assignee Claimed by @weswigham View on GitHub
Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.3k
PR merge metrics
PR metrics pending

Description

## 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:

1. `tsc --noEmit` on a clean tree (writes `tsconfig.tsbuildinfo`) → exits 0.
2. 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, 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).
3. `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` 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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.