microsoft/TypeScript · error · Error
length < 0
Error message
length < 0
What it means
Thrown by `ts.createTextSpan(start, length)` when `length` is negative. Since `createTextSpanFromBounds(start, end)` calls `createTextSpan(start, end - start)`, passing bounds where `end < start` also produces this error.
Source
Thrown at src/compiler/utilitiesPublic.ts:451
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;
}
export function createTextChangeRange(span: TextSpan, newLength: number): TextChangeRange {
View on GitHub (pinned to b465fdbfe1)
Solutions
- Ensure `length >= 0` (and `end >= start` for the bounds variant) before calling.
- Sort the two positions when they can arrive in either order: `const [a, b] = [p, q].sort((x,y)=>x-y);`.
- Use `ts.textSpanIsEmpty` / construct `createTextSpan(pos, 0)` for zero-length needs.
Example fix
// before const span = ts.createTextSpanFromBounds(node.end, node.pos); // end<pos -> length<0 // after const span = ts.createTextSpanFromBounds(node.pos, node.end); // pos <= end
Defensive patterns
Strategy: validation
Validate before calling
function safeSpanFromBounds(start: number, end: number): ts.TextSpan {
if (end < start) [start, end] = [end, start];
return ts.createTextSpanFromBounds(start, end);
} Type guard
function isValidBounds(start: number, end: number): boolean { return Number.isInteger(start) && Number.isInteger(end) && start >= 0 && end >= start; } Prevention
- Always pass `pos` first, `end` second for nodes.
- Sort externally-derived anchor pairs before building a span.
When it happens
Trigger: Calling `createTextSpan` with a negative `length`, or `createTextSpanFromBounds` with reversed/out-of-order `start`/`end` (end before start), usually due to inverted node positions or wrong subtraction order.
Common situations: Transforms computing `end - start` with swapped operands; editing ranges from incremental edits where the new range is empty or inverted; converting selection anchors that can be backwards.
Related errors
- start < 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/c614dd3b94df9dac.
Report an issue: GitHub.