microsoft/TypeScript · error · Error
start < 0
Error message
start < 0
What it means
Thrown by `ts.createTextSpan(start, length)` when `start` is negative. `TextSpan` models a half-open range into source text; a negative start is always a bug in the caller (offset computation underflow). `createTextSpanFromBounds` delegates here via `createTextSpan(start, end - start)`, so out-of-order bounds also surface as this error.
Source
Thrown at src/compiler/utilitiesPublic.ts:448
while (i < spans.length) {
let span = spans[i];
let j = i + 1;
while (j < spans.length && textSpanIntersectsWithTextSpan(span, spans[j])) {
const start = Math.min(span.start, spans[j].start);
const end = Math.max(textSpanEnd(span), textSpanEnd(spans[j]));
span = createTextSpanFromBounds(start, end);
j++;
}
i = j;
result.push(span);
}
return result;
}
export function createTextSpan(start: number, length: number): TextSpan {
if (start < 0) {
throw new Error("start < 0");
}
if (length < 0) {
throw new Error("length < 0");
}
return { start, length };
}
export function createTextSpanFromBounds(start: number, end: number): TextSpan {
return createTextSpan(start, end - start);
}
export function textChangeRangeNewSpan(range: TextChangeRange): TextSpan {
return createTextSpan(range.span.start, range.newLength);
}
export function textChangeRangeIsUnchanged(range: TextChangeRange): boolean {
return textSpanIsEmpty(range.span) && range.newLength === 0;
View on GitHub (pinned to b465fdbfe1)
Solutions
- Clamp `start` to `Math.max(0, computed)` before calling.
- Audit the upstream position math (it should be producing a non-negative absolute offset).
- Use `ts.createTextSpanFromBounds` with verified `start <= end` ordering.
- Add an assertion/log of `start`/`length` at the call site during development.
Example fix
// before const span = ts.createTextSpan(node.end - node.getStart(), len); // can be < 0 // after const start = Math.max(0, node.end - node.getStart()); const span = ts.createTextSpan(start, Math.max(0, len));
Defensive patterns
Strategy: validation
Validate before calling
function safeSpan(start: number, length: number): ts.TextSpan {
if (start < 0 || length < 0) return ts.createTextSpan(0, 0);
return ts.createTextSpan(start, length);
} Type guard
function isValidSpanStart(start: number): boolean { return Number.isInteger(start) && start >= 0; } Prevention
- Always derive spans from already-validated node `pos`/`end`, never from arithmetic that can underflow.
- Clamp external positions to `[0, fileLength]` before constructing spans.
When it happens
Trigger: Calling `createTextSpan` with `start < 0`, or `createTextSpanFromBounds(start, end)` where `start` is negative — typically from subtracting offsets, parsing an empty/malformed node, or off-by-one position math in a transform/language-service plugin.
Common situations: Custom transforms that compute spans from node positions; language-service plugins mishandling end-of-file offsets; converting external 1-based line/column to 0-based absolute positions incorrectly.
Related errors
- length < 0
- newLength < 0
- Could not resolve JS module '${moduleName}' starting at '${i
- ${option.name} is a string value; tsconfig JSON must be pars
- tracing requires having fs\n(original error: ${e.message ||
AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12).
Data as JSON: /api/errors/dbd9abd04efe1f09.
Report an issue: GitHub.