{"record":{"id":"f2360e189edd8553","repo":"openai/codex","slug":"max-lines-must-be-a-positive-integer","errorCode":null,"errorMessage":"max_lines must be a positive integer","messagePattern":"max_lines must be a positive integer","errorType":"validation","errorClass":"MemoriesBackendError","httpStatus":null,"severity":"error","filePath":"codex-rs/ext/memories/src/backend.rs","lineNumber":151,"sourceCode":"}\n\n#[derive(Debug, thiserror::Error)]\npub enum MemoriesBackendError {\n    #[error(\"filename '{filename}' {reason}\")]\n    InvalidFilename { filename: String, reason: String },\n    #[error(\"ad-hoc note must not be empty\")]\n    EmptyAdHocNote,\n    #[error(\"ad-hoc note '{filename}' already exists\")]\n    AdHocNoteAlreadyExists { filename: String },\n    #[error(\"path '{path}' {reason}\")]\n    InvalidPath { path: String, reason: String },\n    #[error(\"cursor '{cursor}' {reason}\")]\n    InvalidCursor { cursor: String, reason: String },\n    #[error(\"path '{path}' was not found\")]\n    NotFound { path: String },\n    #[error(\"line_offset must be a 1-indexed line number\")]\n    InvalidLineOffset,\n    #[error(\"max_lines must be a positive integer\")]\n    InvalidMaxLines,\n    #[error(\"line_offset exceeds file length\")]\n    LineOffsetExceedsFileLength,\n    #[error(\"path '{path}' is not a file\")]\n    NotFile { path: String },\n    #[error(\"queries must not be empty or contain empty strings\")]\n    EmptyQuery,\n    #[error(\"all_within_lines.line_count must be a positive integer\")]\n    InvalidMatchWindow,\n    #[error(\"I/O error while reading memories: {0}\")]\n    Io(#[from] std::io::Error),\n}\n\nimpl MemoriesBackendError {\n    pub fn invalid_filename(filename: impl Into<String>, reason: impl Into<String>) -> Self {\n        Self::InvalidFilename {\n            filename: filename.into(),\n            reason: reason.into(),","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/ext/memories/src/backend.rs#L133-L169","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use max_lines: None to read to the end of the file.","Coerce zero at your boundary: let max_lines = (n > 0).then_some(n);","Fix the upstream page-size setting so it is >= 1."],"exampleFix":"// before\nlet max_lines = Some(page_size); // page_size == 0 means 'unlimited' upstream\n\n// after\nlet max_lines = (page_size > 0).then_some(page_size); // None = read to EOF","handlingStrategy":"validation","validationCode":"// Rust - normalize a page size where 0 means 'unlimited'\nfn normalize_max_lines(max_lines: usize) -> Option<usize> {\n    (max_lines > 0).then_some(max_lines)\n}\n\nlet request = ReadMemoryRequest {\n    path,\n    line_offset: 1,\n    max_lines: normalize_max_lines(page_size),\n    max_tokens: 0,\n};","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Learn the Option semantics once: None = read to EOF, Some(n) = at most n lines, Some(0) is always an error.","Never forward raw config zeros into max_lines; coerce at the boundary.","Unit-test request construction with a zero page size."],"tags":["rust","codex","memories","validation","pagination","option-semantics"],"backgroundTag":"invalid-argument","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}