Hmbown/CodeWhale · error

invalid memory workspace id

Error message

invalid memory workspace id

What it means

safe_component sanitizes strings used as filesystem path components (workspace ids). A value that is empty, '.', '..', or contains '/' or '\' could escape or corrupt the memory directory, so the function refuses it. This is a path-traversal guard applied to every workspace id before it becomes a directory name.

Solutions

  1. Sanitize the workspace id: strip or replace path separators and reject '.'/'..' before calling
  2. Derive the id from a safe slug (alphanumeric, dash, underscore) of the original name
  3. Reject the value upstream in config parsing so an invalid id never reaches workspace_path

Example fix

// before
let ws = user_supplied_name; // "team/sub"
memory.write(ws, note)
// after
let ws = user_supplied_name.replace(['/', '\\'], "-");
if ws.is_empty() || ws == "." || ws == ".." { return Err("bad workspace id"); }
memory.write(ws, note)
Defensive patterns

Strategy: validation

Validate before calling

fn is_safe_component(v: &str) -> bool {
    !(v.is_empty() || v == "." || v == ".." || v.contains('/') || v.contains('\\'))
}

Type guard

fn safe_workspace_id(v: &str) -> Option<&str> {
    if v.is_empty() || v == "." || v == ".." || v.contains('/') || v.contains('\\') { None } else { Some(v) }
}

Try / catch

match memory.workspace_path(id) {
    Ok(path) => path,
    Err(e) if e.to_string().contains("invalid memory workspace id") => {
        return Err(anyhow!("workspace id '{}' contains path separators", id))
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling workspace_path (directly or via memory APIs taking a workspace id) with an id that is empty, equals '.' or '..', or embeds a slash or backslash character.

Common situations: Workspace ids derived from untrusted or user-supplied names like 'team/sub'; Windows-style paths 'a\\b' reaching validation; default/placeholder ids left as '.'; empty id from a missing config field.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/694dfa3fa2fbdcf1. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/native_memory.rs:911

    Ok(note.trim_start_matches('-').trim().to_string())
}

fn validate_query(query: &str) -> Result<&str> {
    let query = query.trim();
    if query.is_empty() || query.chars().count() > MAX_QUERY_CHARS {
        bail!("memory search query is empty or too long");
    }
    Ok(query)
}

fn safe_component(value: &str) -> Result<String> {
    if value.is_empty()
        || value == "."
        || value == ".."
        || value.contains('/')
        || value.contains('\\')
    {
        bail!("invalid memory workspace id");
    }
    Ok(value.to_string())
}

fn ensure_memory_file(path: &Path) -> Result<()> {
    if let Some(parent) = path.parent() {
        fs::create_dir_all(parent)?;
    }
    if !path.exists() {
        File::create(path)?;
    }
    Ok(())
}

fn file_mtime(path: &Path) -> Result<i64> {
    Ok(fs::metadata(path)?
        .modified()?
        .duration_since(UNIX_EPOCH)

View on GitHub (pinned to 433685b202)