openai/codex · warning · MemoriesBackendError

line_offset exceeds file length

Error message

line_offset exceeds file length

What it means

Returned by the memories read path when line_offset is a well-formed 1-indexed number but larger than the number of lines in the file. line_start_byte_offset (codex-rs/ext/memories/src/local/read.rs:53-72) scans for the start of the requested line by counting newlines and never reaches it, so the requested line does not exist. Unlike InvalidLineOffset, the request was valid; the file is simply shorter than the caller assumed.

Source

Thrown at codex-rs/ext/memories/src/backend.rs:153

#[derive(Debug, thiserror::Error)]
pub enum MemoriesBackendError {
    #[error("filename '{filename}' {reason}")]
    InvalidFilename { filename: String, reason: String },
    #[error("ad-hoc note must not be empty")]
    EmptyAdHocNote,
    #[error("ad-hoc note '{filename}' already exists")]
    AdHocNoteAlreadyExists { filename: String },
    #[error("path '{path}' {reason}")]
    InvalidPath { path: String, reason: String },
    #[error("cursor '{cursor}' {reason}")]
    InvalidCursor { cursor: String, reason: String },
    #[error("path '{path}' was not found")]
    NotFound { path: String },
    #[error("line_offset must be a 1-indexed line number")]
    InvalidLineOffset,
    #[error("max_lines must be a positive integer")]
    InvalidMaxLines,
    #[error("line_offset exceeds file length")]
    LineOffsetExceedsFileLength,
    #[error("path '{path}' is not a file")]
    NotFile { path: String },
    #[error("queries must not be empty or contain empty strings")]
    EmptyQuery,
    #[error("all_within_lines.line_count must be a positive integer")]
    InvalidMatchWindow,
    #[error("I/O error while reading memories: {0}")]
    Io(#[from] std::io::Error),
}

impl MemoriesBackendError {
    pub fn invalid_filename(filename: impl Into<String>, reason: impl Into<String>) -> Self {
        Self::InvalidFilename {
            filename: filename.into(),
            reason: reason.into(),
        }
    }

View on GitHub (pinned to 339751715c)

Solutions

  1. Treat this error as end-of-file and stop paginating.
  2. Resynchronize by re-reading from line_offset 1 (or re-listing) when it fires.
  3. If you must continue, count the file's lines first and clamp line_offset to that count.
  4. Drive pagination from the latest response's start_line_number and truncated flag, not cached offsets.

Example fix

// before
loop {
    let resp = backend.read(req_at(offset)).await?; // fails at EOF
    if !resp.truncated { break; }
    offset += 200;
}

// after
loop {
    let resp = match backend.read(req_at(offset)).await {
        Ok(resp) => resp,
        Err(MemoriesBackendError::LineOffsetExceedsFileLength) => break, // end of file
    };
    if !resp.truncated { break; }
    offset += 200;
}
Defensive patterns

Strategy: try-catch

Try / catch

match backend.read(request).await {
    Ok(resp) => { /* render */ }
    Err(MemoriesBackendError::LineOffsetExceedsFileLength) => {
        // normal end-of-pagination outcome: stop, do not surface as failure
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Paginating with an offset captured from an earlier read after the file shrank; computing line_offset from stale file info; another process (sync tool, second session) rewriting or trimming the memory file between reads; an offset greater than the total line count.

Common situations: Memory notes edited concurrently while a reader walks them; retry logic reusing offsets from an older, longer version; UIs that keep a scroll position as a line number.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/58f498fd8bfa2383. Report an issue: GitHub.