astrid-runtime/astrid · error

Invalid session ID (must be a UUID)

Error message

Invalid session ID (must be a UUID): {id}

What it means

delete_session validates the session id as a UUID before touching the filesystem, specifically to prevent path traversal such as '../../config'. If uuid::Uuid::parse_str rejects the id, this error is returned and no directory is ever joined or removed.

Solutions

  1. Run the sessions list command and copy the exact UUID for the session
  2. Trim whitespace/quotes and use only the raw UUID (hyphenated form works)
  3. Verify the id is a valid UUID (e.g. uuidgen or an online validator) before retrying
  4. If the ID came from a script, quote and parse it properly to avoid mangling

Example fix

// before
astrid sessions delete ../../config
// after
astrid sessions delete 3f2b8c1a-9d4e-4f01-b2a3-5c6d7e8f9012
Defensive patterns

Strategy: validation

Validate before calling

fn is_uuid(s: &str) -> bool { uuid::Uuid::parse_str(s).is_ok() }
if !is_uuid(id) { eprintln!("{id} is not a UUID; copy the id from `astrid sessions list`"); return; }

Type guard

fn is_uuid(s: &str) -> bool { uuid::Uuid::parse_str(s).is_ok() }

Try / catch

match delete_session(id) {
    Ok(()) => println!("deleted"),
    Err(e) if e.to_string().starts_with("Invalid session ID") => eprintln!("Pass the full UUID shown by `astrid sessions list`"),
    Err(e) => eprintln!("delete failed: {e}"),
}

Prevention

When it happens

Trigger: Calling delete_session with an id string that is not a canonical UUID — arbitrary names, relative paths, truncated IDs, extra whitespace, or braces-wrapped UUIDs.

Common situations: Passing a session name/short label instead of the UUID from `astrid sessions list`; copy-paste errors including quotes or path characters; scripting with stale or hand-edited IDs.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/9e5efa08b7128c9b. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-cli/src/commands/sessions.rs:56

    sessions.sort_by_key(|s| std::cmp::Reverse(s.1));

    println!("{}", "Active Sessions:".bold());
    for (id, modified) in sessions {
        let time = chrono::DateTime::<chrono::Local>::from(modified)
            .format("%Y-%m-%d %H:%M:%S")
            .to_string();
        println!("  {} ({})", Theme::session_id(&id), Theme::dimmed(&time));
    }

    Ok(())
}

/// Delete a session by UUID.
pub(crate) fn delete_session(id: &str) -> Result<()> {
    // Validate as UUID to prevent path traversal (e.g. "../../config")
    uuid::Uuid::parse_str(id)
        .map_err(|_| anyhow::anyhow!("Invalid session ID (must be a UUID): {id}"))?;
    let home = AstridHome::resolve().context("Failed to resolve Astrid home directory")?;
    let session_dir = home.run_dir().join(id);

    if !session_dir.exists() {
        anyhow::bail!("Session not found: {id}");
    }

    fs::remove_dir_all(&session_dir)?;
    println!("{}", Theme::success(&format!("Deleted session {id}")));
    Ok(())
}

/// Show information about a session by UUID.
pub(crate) fn session_info(id: &str) -> Result<()> {
    uuid::Uuid::parse_str(id)
        .map_err(|_| anyhow::anyhow!("Invalid session ID (must be a UUID): {id}"))?;
    let home = AstridHome::resolve().context("Failed to resolve Astrid home directory")?;
    let session_dir = home.run_dir().join(id);

View on GitHub (pinned to affd8760f4)