openai/codex · error · MemoriesBackendError

path '{path}' {reason}

Error message

path '{path}' {reason}

What it means

The path argument to list/read/search failed validation; the reason string names the exact problem. The MemoriesBackend contract keeps paths relative to the memory store, so absolute paths and traversal are rejected by design.

Source

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

#[derive(Debug, Clone, PartialEq, Eq, Serialize, JsonSchema)]
#[schemars(deny_unknown_fields)]
pub struct MemorySearchMatch {
    pub path: String,
    pub match_line_number: usize,
    pub content_start_line_number: usize,
    pub content: String,
    pub matched_queries: Vec<String>,
}

#[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}")]

View on GitHub (pinned to 339751715c)

Solutions

  1. Pass store-relative paths ('notes/foo.md', not '/home/.../notes/foo.md').
  2. Normalize: strip leading slashes and reject '..' segments before calling.
  3. Consult the reason text for the specific rule that was tripped.

Example fix

// before
let req = ReadMemoryRequest { path: "/home/user/store/notes/a.md".into(), .. };

// after
let req = ReadMemoryRequest { path: "notes/a.md".into(), .. };
Defensive patterns

Strategy: validation

Validate before calling

let path = normalize_store_path(&raw_path)?; // strip leading '/', collapse '//'
if !is_valid_store_path(&path) {
    return Err(MemoriesBackendError::invalid_path(path, "absolute or traversing paths are not allowed"));
}

Type guard

fn is_valid_store_path(path: &str) -> bool {
    !path.is_empty()
        && !path.starts_with('/')
        && !path.split('/').any(|seg| seg.is_empty() || seg == ".." || seg == ".")
}

Prevention

When it happens

Trigger: Passing a path starting with '/' or a drive letter, containing '..' components, empty segments, or otherwise violating the backend's relative-path rules.

Common situations: Feeding absolute host filesystem paths into memory tools; concatenated input producing 'a/../b'; Windows-style separators.

Related errors


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