zed-industries/zed · error

cursor position marker line must contain '^' or '<' before [

Error message

cursor position marker line must contain '^' or '<' before [CURSOR_POSITION]

What it means

Cursor-extraction in example specs: the marker line is the line containing `[CURSOR_POSITION]`; the column is taken from a `^` under the target column, or from the first non-whitespace char when `<` is used; if the marker line contains neither `^` nor `<` before the marker there is no way to compute the column and the parser bails (example_spec.rs:456).

Source

Thrown at crates/edit_prediction/src/example_spec.rs:456

            .context("missing [CURSOR_POSITION] marker")?;
        let marker_line_start = input[..marker_offset]
            .rfind('\n')
            .map(|pos| pos + 1)
            .unwrap_or(0);
        let marker_line_end = input[marker_line_start..]
            .find('\n')
            .map(|pos| marker_line_start + pos + 1)
            .unwrap_or(input.len());
        let marker_line = &input[marker_line_start..marker_line_end].trim_end_matches('\n');

        let cursor_column = if let Some(cursor_offset) = marker_line.find('^') {
            cursor_offset
        } else if let Some(less_than_pos) = marker_line.find('<') {
            marker_line
                .find(|c: char| !c.is_whitespace())
                .unwrap_or(less_than_pos)
        } else {
            anyhow::bail!(
                "cursor position marker line must contain '^' or '<' before [CURSOR_POSITION]"
            );
        };

        let mut excerpt = input[..marker_line_start].to_string() + &input[marker_line_end..];
        excerpt.truncate(excerpt.trim_end_matches('\n').len());

        // The cursor is on the line above the marker line.
        let cursor_line_end = marker_line_start.saturating_sub(1);
        let cursor_line_start = excerpt[..cursor_line_end]
            .rfind('\n')
            .map(|pos| pos + 1)
            .unwrap_or(0);
        let cursor_offset = cursor_line_start + cursor_column;

        Ok((excerpt, cursor_offset))
    }

View on GitHub (pinned to f4178619ac)

Solutions

  1. Put `^` in the marker line at the exact column under the target character: ` ^ [CURSOR_POSITION]`.
  2. Or use `<` when marking before code text — the first non-whitespace char after `<` sets the column.
  3. Keep the marker line directly below the cursor line; do not remove the arrow character.

Example fix

```cursor
src/main.rs
let value = compute(x);
[CURSOR_POSITION]        // before — no ^ or < on the marker line
```

```cursor
src/main.rs
let value = compute(x);
            ^ [CURSOR_POSITION]   // after — caret under the target column
```
Defensive patterns

Strategy: validation

Validate before calling

// check the marker line shape before parsing specs
let marker = line_containing(spec_text, "[CURSOR_POSITION]");
if !marker.contains('^') && !marker.contains('<') {
    return Err(anyhow!("marker line needs ^ or < before [CURSOR_POSITION]"));
}

Type guard

fn is_valid_marker_line(line: &str) -> bool {
    line.contains("[CURSOR_POSITION]") && (line.contains('^') || line.contains('<'))
}

Prevention

When it happens

Trigger: A cursor block whose marker line is only `[CURSOR_POSITION]`, or uses a different caret character ( `~`, `|` ), or where the arrow was deleted while editing the spec.

Common situations: Hand-editing marker lines; copy-paste that drops the caret; specs written without reading the marker convention (`^` points at the column, `<` marks a position left of code).

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/efa36285e71b194f. Report an issue: GitHub.