facebook/flow · error

Invalid position: {{line: {}; column: {}}}

Error message

Invalid position: {{line: {}; column: {}}}

What it means

file_content::get_offsets() scans a file's bytes to convert two 1-based Positions (line, column) into byte offsets. If a position is never reached while scanning — the line or column is past the end of the content — invalid_position() panics with the offending line/column. This helper backs position-based server queries, so bad positions from any client surface here.

Source

Thrown at rust_port/crates/flow_server_utils/src/file_content.rs:85

        }
        if acc.0.is_some() && acc.1.is_none() && is_target(queries.1, line, column) {
            acc.1 = Some(offset);
            continue;
        }
        let c = get_char(content, offset);
        if c == b'\n' {
            line += 1;
            column = 1;
            offset += 1;
        } else {
            column += 1;
            offset += get_char_length(c);
        }
    }
}

fn invalid_position(p: &Position) -> ! {
    panic!(
        "Invalid position: {{line: {}; column: {}}}",
        p.line, p.column
    )
}

pub fn get_offsets(content: &str, queries: (&Position, &Position)) -> (usize, usize) {
    match get_offsets_rec(content.as_bytes(), queries, 1, 1, 0, (None, None)) {
        (Some(r1), Some(r2)) => (r1, r2),
        (None, _) => invalid_position(queries.0),
        (_, None) => invalid_position(queries.1),
    }
}

pub fn get_offset(content: &str, position: &Position) -> usize {
    get_offsets(content, (position, position)).0
}

pub fn offset_to_position(content: &str, offset: usize) -> Position {

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Re-fetch the content and compute positions against exactly that text, in the same synchronization frame as the query.
  2. Clamp before sending: line to the number of lines, column to the target line's length + 1.
  3. Send 1-based line and column values.
  4. If you fork: make get_offsets return Result and translate out-of-range positions into a clean error response instead of a panic.

Example fix

// before: position computed from a stale buffer
const pos = oldBuffer.positionAt(cursorOffset);
sendQuery({ line: pos.line, column: pos.column });

// after: clamp against the content the server holds
const lines = currentContent.split('\n');
const line = Math.min(reqLine, lines.length);
const column = Math.min(reqColumn, lines[line - 1].length + 1);
sendQuery({ line, column });
Defensive patterns

Strategy: validation

Validate before calling

function positionInRange(content, line, column) {
  const lines = content.split('\n');
  return line >= 1 && line <= lines.length &&
         column >= 1 && column <= lines[line - 1].length + 1;
}

// before sending any position query
if (!positionInRange(serverContent, line, column)) {
  const clamped = clampPosition(serverContent, line, column);
  ({ line, column } = clamped);
}

Type guard

function positionInRange(content: string, line: number, column: number): boolean {
  const lines = content.split('\n');
  return Number.isInteger(line) && Number.isInteger(column) &&
         line >= 1 && line <= lines.length &&
         column >= 1 && column <= lines[line - 1].length + 1;
}

Prevention

When it happens

Trigger: A client sends a position beyond EOF (line greater than the file's line count, or column greater than that line's length); positions computed against a different version of the content than the server holds (race between didChange and the query); 0-based line/column values from a client that should be 1-based.

Common situations: Editor queries racing file saves; clients being off-by-one on the line/column base; queries positioned one past the end of the last line; CRLF/BOM differences making the client's column math disagree with the server's bytes; stale buffers after external file changes (git checkout, formatter).

Related errors


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/4fbe7165d6e5ec7f. Report an issue: GitHub.