microsoft / microsoft/TypeScript
Debug Failure: "No error for last overload signature" crash when CustomTypeOptions.resources uses typeof on a large (~10k line) JSON file
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
## Bug Report
**TypeScript version:** 5.7.2 (also reproduced on 6.0.0-beta)
**i18next version:** 24.2.2
**react-i18next version:** 15.4.0
**Node:** 22.9.0
---
## Summary
TypeScript crashes with an internal `Debug Failure` when:
1. A `.d.ts` file augments i18next's `CustomTypeOptions.resources` using `typeof` on a large JSON file (~10k lines), and
2. TypeScript resolves the `t()` function's overloads against that resource type.
This is a compiler crash — not a type error surfaced to the user — so it always represents a broken invariant inside the checker.
---
## Reproduction
### File structure
```
src/
i18next.d.ts
public/assets/locales/en/translation.json ← ~10,000 lines, deeply nested
```
### `src/i18next.d.ts`
```ts
import type translation from '../public/assets/locales/en/translation.json';
declare module 'i18next' {
interface CustomTypeOptions {
defaultNS: 'translation';
resources: {
translation: typeof translation;
};
}
}
```
### `tsconfig.app.json` (relevant parts)
```json
{
"compilerOptions": {
"moduleResolution": "bundler",
"resolveJsonModule": true,
"paths": {
"@locales/*": ["./public/assets/locales/*"]
}
},
"include": ["src"]
}
```
### Running `tsc --noEmit`
```
error TS2Function: Debug Failure. No error for last overload signature.
```
The process exits non-zero. No useful file/line information is attached to the diagnostic.
---
## Key observations
| Condition | Crashes? |
|-----------|----------|
| `typeof` on the full 10,085-line JSON | ✅ Yes |
| Replaced with a small hand-written type (same shape, ~20 keys) | ❌ No |
| `CustomTypeOptions` tuned with `returnNull: false`, `returnEmptyString: false`, `jsonFormat: "v4"` | ✅ Still crashes |
| `import type` instead of `import` | ✅ Still crashes |
| `resolveJsonModule` toggled | ✅ Still crashes |
The crash is **scale-triggered**: the combination of i18next's multi-overload `t()` signature and the deeply-nested union type produced by `typeof largeJson` causes the overload checker to reach an assertion it cannot satisfy.
---
## Why this is a TypeScript bug
`Debug Failure` diagnostics are internal `Debug.assert()` calls that should **never** reach the user. Regardless of how complex or unusual the input types are, the compiler must either:
- produce a proper type error, or
- succeed silently.
Crashing with an assertion failure when resolving overloads against a large `typeof` type is a broken invariant in the checker.
---
## Workarounds (all unsatisfactory)
- Commit with `--no-verify` to skip the typecheck step
- Replace `typeof translation` with a hand-maintained `TranslationKeys` type (defeats the purpose of auto-typed i18n)
- Suppress with `// @ts-ignore` across all call sites
---
## Additional context
The `t()` function in i18next 24.x has dozens of overloads that distribute over the resource namespace union. When the resource type has thousands of deeply-nested keys (as is common in production i18n files), the overload resolution cartesian-products the key space and appears to hit an unchecked branch in the "last overload must produce an error" logic.
A stack trace from the crash (abbreviated):
```
TypeError: Debug Failure. No error for last overload signature.
at resolveOverload (typescript/lib/typescript.js)
at getResolvedSignature (typescript/lib/typescript.js)
at checkCallExpression (typescript/lib/typescript.js)
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the crash with the described i18next declaration, large JSON resource, and `tsc --noEmit`. Start at `resolveOverload` in `typescript/lib/typescript.js`, then trace `getResolvedSignature` and `checkCallExpression`; done means the same overload-resolution case no longer produces an internal Debug Failure and instead succeeds or reports a normal diagnostic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100