🔎 Search Terms
panic Diagnostic emitted without context, declaration emit crash, throwDiagnostic, handleSymbolAccessibilityError, transformExportAssignment, canProduceDiagnostics, export default arrow function, function expression, inferred return type cannot be named, symbol accessibility, TS4082, tsgo, native compiler
🕗 Version & Regression Information
⏯ Playground Link
No response
💻 Code
// @filename: helper.ts
declare const brand: unique symbol;
class Foo {
private [brand]: number = 1;
}
export function makeFoo() {
return new Foo();
}
// @filename: repro.ts
import { makeFoo } from './helper';
export default () => makeFoo();
Run tsc -p ..
Both ingredients are required: the default export must be an ExportAssignment whose expression is an
arrow function or function expression (export default function () {} at statement level is a
function declaration a different AST node and errors correctly), and the inferred return type
must contain a symbol that cannot be named from the exporting module.
🙁 Actual behavior
The whole compile crashes with a Go panic (exit code 2) instead of reporting a diagnostic:
panic: Diagnostic emitted without context [recovered, repanicked]
github.com/microsoft/typescript-go/internal/transformers/declarations.throwDiagnostic(...)
internal/transformers/declarations/transform.go:276
...(*SymbolTrackerImpl).handleSymbolAccessibilityError(...) // Accessibility = CannotBeNamed, ErrorNode = nil
internal/transformers/declarations/tracker.go:211
...(*NodeBuilderImpl).serializeReturnTypeForSignature
...(*DeclarationTransformer).ensureType transform.go:1647
...(*DeclarationTransformer).transformFunctionLikeToDeclaration
...(*DeclarationTransformer).transformExportAssignment transform.go:1223
In a large monorepo this also fires under noEmit + incremental (declaration transforms run for
buildinfo state), where transient stale-cache states can create the cannot be named condition on
otherwise-clean code making the crash appear nondeterministic.
🙂 Expected behavior
A normal diagnostic, as TypeScript 6.0.3 emits for the identical input:
repro.ts(3,1): error TS4082: Default export of the module has or is using private name 'brand'.
tsgo itself handles every neighbouring form correctly — only the expression-form default export panics:
| form |
result (tsgo 7.0.2 / nightly) |
export default () => makeFoo(); |
panic |
export default (function () { … }); |
panic |
export default function () { … } (declaration) |
TS4058 ✓ |
export const make = () => makeFoo(); |
TS4023 + TS4094 ✓ |
Additional information about the issue
Root cause (verified at tag typescript/v7.0.2, commit 2bd066d8, and unchanged on current main):
visitSourceFile installs throwDiagnostic literally panic("Diagnostic emitted without context") as the file-level default getSymbolAccessibilityDiagnostic
(internal/transformers/declarations/transform.go:276, :289).
transformExportAssignment's ast.IsFunctionLike(unwrapped) branch (transform.go ~1241 on main),
which promotes export default <arrow/function expression> via
transformFunctionLikeToDeclaration → ensureType(unwrapped), returns without installing a
diagnostic context and without PushErrorFallbackNode unlike the non-function fallback
branch just below it, which installs Default_export_of_the_module_has_or_is_using_private_name_0
before serializing.
ensureType installs a per-node handler only if canProduceDiagnostics(node) (transform.go ~1671
on main), and canProduceDiagnostics (internal/transformers/declarations/util.go:25) does not
include ast.IsArrowFunction / ast.IsFunctionExpression.
So a SymbolAccessibilityCannotBeNamed result raised while serializing the arrow's inferred return
type reaches the panic stub and takes down the compiler.
Suggested minimal fix: in the IsFunctionLike branch, install the same default-export diagnostic
context (and PushErrorFallbackNode(assignment) / Pop) that the sibling fallback branch already
uses, before calling transformFunctionLikeToDeclaration. This restores parity with TS 6.x (TS4082).
Prior occurrences of the same panic via other triggers: microsoft/typescript-go#2522 (CommonJS .cjs
re-export — fixed for that trigger only), microsoft/typescript-go#3378 (LSP, closed unverified).
Observed in the wild: supabase/supabase#48876 (worked around by deleting the triggering code).
🔎 Search Terms
panic Diagnostic emitted without context, declaration emit crash, throwDiagnostic, handleSymbolAccessibilityError, transformExportAssignment, canProduceDiagnostics, export default arrow function, function expression, inferred return type cannot be named, symbol accessibility, TS4082, tsgo, native compiler
🕗 Version & Regression Information
typescript@next7.1.0-dev.20260819.1typescript@7.0.2,@typescript/native-preview7.0.0-dev.20260707.2,typescript@next7.1.0-dev.20260819.1), and I reviewed the FAQ for entries about declaration emit and "has or is using private name" errors — none cover compiler panics⏯ Playground Link
No response
💻 Code
Run
tsc -p ..Both ingredients are required: the default export must be an ExportAssignment whose expression is an
arrow function or function expression (
export default function () {}at statement level is afunction declaration a different AST node and errors correctly), and the inferred return type
must contain a symbol that cannot be named from the exporting module.
🙁 Actual behavior
The whole compile crashes with a Go panic (exit code 2) instead of reporting a diagnostic:
In a large monorepo this also fires under
noEmit+incremental(declaration transforms run forbuildinfo state), where transient stale-cache states can create the cannot be named condition on
otherwise-clean code making the crash appear nondeterministic.
🙂 Expected behavior
A normal diagnostic, as TypeScript 6.0.3 emits for the identical input:
tsgo itself handles every neighbouring form correctly — only the expression-form default export panics:
export default () => makeFoo();export default (function () { … });export default function () { … }(declaration)export const make = () => makeFoo();Additional information about the issue
Root cause (verified at tag
typescript/v7.0.2, commit 2bd066d8, and unchanged on currentmain):visitSourceFileinstallsthrowDiagnosticliterallypanic("Diagnostic emitted without context")as the file-level defaultgetSymbolAccessibilityDiagnostic(internal/transformers/declarations/transform.go:276, :289).
transformExportAssignment'sast.IsFunctionLike(unwrapped)branch (transform.go ~1241 on main),which promotes
export default <arrow/function expression>viatransformFunctionLikeToDeclaration → ensureType(unwrapped), returns without installing adiagnostic context and without
PushErrorFallbackNodeunlike the non-function fallbackbranch just below it, which installs
Default_export_of_the_module_has_or_is_using_private_name_0before serializing.
ensureTypeinstalls a per-node handler onlyif canProduceDiagnostics(node)(transform.go ~1671on main), and
canProduceDiagnostics(internal/transformers/declarations/util.go:25) does notinclude
ast.IsArrowFunction/ast.IsFunctionExpression.So a
SymbolAccessibilityCannotBeNamedresult raised while serializing the arrow's inferred returntype reaches the panic stub and takes down the compiler.
Suggested minimal fix: in the
IsFunctionLikebranch, install the same default-export diagnosticcontext (and
PushErrorFallbackNode(assignment)/Pop) that the sibling fallback branch alreadyuses, before calling
transformFunctionLikeToDeclaration. This restores parity with TS 6.x (TS4082).Prior occurrences of the same panic via other triggers: microsoft/typescript-go#2522 (CommonJS
.cjsre-export — fixed for that trigger only), microsoft/typescript-go#3378 (LSP, closed unverified).
Observed in the wild: supabase/supabase#48876 (worked around by deleting the triggering code).