openai/codex · error · MemoriesBackendError

max_lines must be a positive integer

Error message

max_lines must be a positive integer

What it means

Thrown by the memories read path (codex-rs/ext/memories/src/local/read.rs:19-21) when ReadMemoryRequest.max_lines is Some(0). The field is Option<usize>: None means read from line_offset to the end of the file, Some(n) means at most n lines. Some(0) requests zero lines, which is meaningless, so it is rejected before any filesystem access; the tool schema also declares schemars range(min = 1).

Source

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

}

#[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. Use max_lines: None to read to the end of the file.
  2. Coerce zero at your boundary: let max_lines = (n > 0).then_some(n);
  3. Fix the upstream page-size setting so it is >= 1.

Example fix

// before
let max_lines = Some(page_size); // page_size == 0 means 'unlimited' upstream

// after
let max_lines = (page_size > 0).then_some(page_size); // None = read to EOF
Defensive patterns

Strategy: validation

Validate before calling

// Rust - normalize a page size where 0 means 'unlimited'
fn normalize_max_lines(max_lines: usize) -> Option<usize> {
    (max_lines > 0).then_some(max_lines)
}

let request = ReadMemoryRequest {
    path,
    line_offset: 1,
    max_lines: normalize_max_lines(page_size),
    max_tokens: 0,
};

Prevention

When it happens

Trigger: Passing Some(0) to mean 'no limit' (the API uses None for that); forwarding a page-size setting of 0 into max_lines; pagination arithmetic that computes a zero lines-remaining value and passes it anyway.

Common situations: Mapping a config where 0 means 'unlimited' onto this API; clamping or saturating math producing 0; hand-built ReadMemoryRequest values in tests or custom tool executors.

Related errors


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