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

  1. Ensure `length >= 0` (and `end >= start` for the bounds variant) before calling.
  2. Sort the two positions when they can arrive in either order: `const [a, b] = [p, q].sort((x,y)=>x-y);`.
  3. 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

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


AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12). Data as JSON: /api/errors/c614dd3b94df9dac. Report an issue: GitHub.