{"record":{"id":"b3802eec0204e643","repo":"openai/codex","slug":"queries-must-not-be-empty-or-contain-empty-strings","errorCode":null,"errorMessage":"queries must not be empty or contain empty strings","messagePattern":"queries must not be empty or contain empty strings","errorType":"validation","errorClass":"MemoriesBackendError","httpStatus":null,"severity":"error","filePath":"codex-rs/ext/memories/src/backend.rs","lineNumber":157,"sourceCode":"    #[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(),\n        }\n    }\n\n    pub fn invalid_path(path: impl Into<String>, reason: impl Into<String>) -> Self {\n        Self::InvalidPath {\n            path: path.into(),","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/ext/memories/src/backend.rs#L139-L175","documentation":"Thrown by the memories search path (codex-rs/ext/memories/src/local/search.rs:21-28) before any scanning happens. Every string in SearchMemoriesRequest.queries is trimmed, then the request is rejected if the resulting list is empty or if any single query is empty after trimming. Empty needles would match every line, so the backend treats them as a caller bug.","triggerScenarios":"queries: vec![] ; a query list containing an empty string or a whitespace-only string such as '   '; splitting user input on a delimiter and keeping empty tokens; forwarding an empty search-box value.","commonSituations":"Search forms submitted blank; input.split(',') or split(' ') producing empty pieces; queries assembled from optional fields where every field was None.","solutions":["Trim and filter queries before the call, and bail out early if nothing remains.","Tokenize with split_whitespace() instead of split(' ').","Reject empty searches at the UI boundary so they never reach the backend."],"exampleFix":"// before\nlet queries: Vec<String> = input.split(',').map(str::to_string).collect();\nbackend.search(SearchMemoriesRequest { queries, .. }).await?;\n\n// after\nlet queries: Vec<String> = input\n    .split(',')\n    .map(str::trim)\n    .filter(|s| !s.is_empty())\n    .map(str::to_string)\n    .collect();\nif queries.is_empty() {\n    return Ok(empty_search_response());\n}\nbackend.search(SearchMemoriesRequest { queries, .. }).await?;","handlingStrategy":"validation","validationCode":"// Rust - build query lists that can never trip EmptyQuery\nfn sanitize_queries(raw: &str) -> Vec<String> {\n    raw.split(&[',', ' '][..])\n        .map(str::trim)\n        .filter(|s| !s.is_empty())\n        .map(str::to_string)\n        .collect()\n}\n\nlet queries = sanitize_queries(&input);\nif queries.is_empty() {\n    return Ok(empty_search_response());\n}","typeGuard":"// Rust - predicate mirroring the backend check (applied after trim)\nfn queries_valid(queries: &[String]) -> bool {\n    !queries.is_empty() && queries.iter().all(|q| !q.trim().is_empty())\n}","tryCatchPattern":null,"preventionTips":["Trim and filter query tokens before calling search().","Use split_whitespace rather than split(' ') when tokenizing.","Gate empty searches at the input boundary."],"tags":["rust","codex","memories","search","validation","empty-input"],"backgroundTag":"empty-search-query","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}