microsoft/typescript-go · error

Bad line number. Line: ${line}, lineStarts.length: ${lineSta

Error message

Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length}

What it means

Thrown by RemoteSourceFile.getPositionOfLineAndCharacter when the requested line is negative or >= lineStarts.length (the number of lines in the file's text). Lines are strictly 0-based and computed from the snapshot's text; the guard rejects any line index outside the file, including the classic 1-based off-by-one.

Source

Thrown at _packages/native-preview/src/api/node/node.ts:261

        return text;
    }

    // ═══ Line/character position mapping ═══

    getLineStarts(): readonly number[] {
        return this._lineStarts ??= computeLineStarts(this.text ?? "");
    }

    getLineAndCharacterOfPosition(position: number): LineAndCharacter {
        const lineStarts = this.getLineStarts();
        const line = computeLineOfPosition(lineStarts, position);
        return { line, character: position - lineStarts[line] };
    }

    getPositionOfLineAndCharacter(line: number, character: number): number {
        const lineStarts = this.getLineStarts();
        if (line < 0 || line >= lineStarts.length) {
            throw new Error(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length}`);
        }
        return lineStarts[line] + character;
    }
}

/**
 * Find the 0-based line number containing the given position via binary search.
 * Assumes the first line starts at position 0 and `position` is non-negative.
 */
function computeLineOfPosition(lineStarts: readonly number[], position: number): number {
    let low = 0;
    let high = lineStarts.length - 1;
    while (low <= high) {
        const middle = low + ((high - low) >> 1);
        const value = lineStarts[middle];
        if (value < position) {
            low = middle + 1;
        }

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Convert external 1-based lines to 0-based before calling (subtract 1)
  2. Validate against the file itself: line >= 0 && line < sourceFile.getLineStarts().length before the call
  3. Recompute positions from the same text snapshot you query (avoid mixing versions)
  4. Clamp instead of throwing when the position is merely past-the-end by design

Example fix

// before
const pos = sf.getPositionOfLineAndCharacter(lineFromDiagnostics, col); // 1-based -> throws

// after
const line = Math.max(0, Math.min(lineFromDiagnostics - 1, sf.getLineStarts().length - 1));
const pos = sf.getPositionOfLineAndCharacter(line, col);
Defensive patterns

Strategy: validation

Validate before calling

// Validate/clamp the line against this exact file before converting
const lineCount = sf.getLineStarts().length;
if (line < 0) throw new RangeError('negative line');
const safeLine = Math.min(line, lineCount - 1); // clamp instead of throwing when past-end is benign
const pos = sf.getPositionOfLineAndCharacter(safeLine, character);

Type guard

const isValidLine = (sf: { getLineStarts(): readonly number[] }, line: number): boolean =>
    Number.isInteger(line) && line >= 0 && line < sf.getLineStarts().length;

Try / catch

try {
    offset = sf.getPositionOfLineAndCharacter(line, character);
} catch (e) {
    if (e instanceof Error && e.message.includes('Bad line number')) {
        // stale or 1-based input: recompute from a fresh snapshot, or clamp
        offset = sf.positionAt(sf.getLineStarts()[sf.getLineStarts().length - 1]);
    } else throw e;
}

Prevention

When it happens

Trigger: Passing a 1-based line from user input, an editor, or a diagnostic payload; using a line computed against a newer/older version of the file than the text backing this RemoteSourceFile; line === lineStarts.length (one past the last line, common when appending); empty/synthetic files where lineStarts has a single entry.

Common situations: Converting IDE positions (often 1-based) or compiler API line numbers to offsets; stale buffers after edits; scripts iterating to <= line count; feeds from logs/tsserver-style data that are 1-based.

Related errors


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/a7dec913abd65544. Report an issue: GitHub.