xai-org/grok-build · error
Error: --session-id must be a valid UUID (got '{session_id}'
Error message
Error: --session-id must be a valid UUID (got '{session_id}'). What it means
`ensure_session_id_available` is a preflight check run before the ACP `session/new` handshake. Because the agent rejects any non-UUID `_meta.sessionId`, the CLI fails fast with this clear message when the `--session-id` value cannot be parsed by `uuid::Uuid::try_parse`. This surfaces the problem at CLI startup instead of as an opaque protocol error mid-handshake.
Source
Thrown at crates/codegen/xai-grok-pager/src/app/session_startup.rs:796
);
auth
}
/// Pre-TUI remote restore (session state and memory only).
/// Codebase checkout is never applied on this path; `--restore-code` requires `--worktree`.
const REMOTE_RESTORE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(90);
/// `--restore-code` without `--worktree` on a remote miss: refuse in-place checkout.
const REMOTE_RESTORE_NEEDS_WORKTREE: &str = "--restore-code on a remote session requires --worktree \
(refusing to check out snapshot code into the current directory)";
/// `--worktree` resume without `--restore-code`: conversation only.
pub(crate) const WORKTREE_NO_RESTORE_CODE_NOTICE: &str =
"Snapshot code will not be restored into the worktree; pass --restore-code to restore it.";
/// Preflight: preferred id must be a UUID and not a persisted session under `cwd`.
///
/// Agent `session/new` rejects non-UUID `_meta.sessionId`; fail fast here so
/// CLI users get a clear error before ACP.
pub fn ensure_session_id_available(session_id: &str, cwd: &str) -> anyhow::Result<()> {
if uuid::Uuid::try_parse(session_id).is_err() {
anyhow::bail!("Error: --session-id must be a valid UUID (got '{session_id}').");
}
if xai_grok_shell::session::persistence::session_exists_for_cwd(session_id, cwd) {
anyhow::bail!("Error: Session ID {session_id} is already in use.");
}
Ok(())
}
/// Materialize CLI intent into a concrete startup plan (I/O + remote restore).
pub async fn materialize_startup(
ctx: MaterializeCtx,
intent: SessionStartupIntent,
) -> anyhow::Result<MaterializedStartup> {
let cwd = std::env::current_dir()
.map_err(|e| anyhow::anyhow!("Failed to get cwd: {e}"))?
.to_string_lossy()
.to_string();
materialize_startup_for_cwd(ctx, intent, &cwd).await
}
/// Same as [`materialize_startup`] but with an explicit process cwd (tests, headless).View on GitHub (pinned to bc7f02eddd)
Solutions
- Pass a valid UUID for `--session-id`, e.g. generate one with `uuidgen` or `python -c 'import uuid; print(uuid.uuid4())'`.
- If you just want a fresh session, drop `--session-id` entirely and let the CLI use `SessionStartupIntent::NewAuto`.
- If resuming an existing session, use `--resume` with the stored session's ID rather than re-typing it.
- Trim/copy the UUID carefully — validate locally with `Uuid::parse_str` or a regex before invoking.
Example fix
// before xai-grok --session-id my-session // after NEW_ID=$(uuidgen) xai-grok --session-id "$NEW_ID"
Defensive patterns
Strategy: validation
Validate before calling
use uuid::Uuid;
fn validate_session_id(session_id: &str) -> Result<(), String> {
Uuid::try_parse(session_id)
.map(|_| ())
.map_err(|_| format!("--session-id must be a valid UUID (got '{session_id}')."))
}
// call before launching: validate_session_id(&args.session_id)?; Type guard
fn is_valid_uuid(s: &str) -> bool {
uuid::Uuid::try_parse(s).is_ok()
} Try / catch
match ensure_session_id_available(&session_id, cwd) {
Err(e) if e.to_string().contains("must be a valid UUID") => {
eprintln!("Please pass a proper UUID, e.g. --session-id $(uuidgen)");
std::process::exit(1);
}
other => other?,
} Prevention
- Generate IDs with uuidgen / Uuid::new_v4() instead of typing them.
- Validate UUID format in wrapper scripts before invoking the CLI.
- Prefer omitting --session-id (NewAuto) unless an explicit ID is required.
- Copy-paste UUIDs in full; check for truncation, whitespace, or surrounding quotes.
When it happens
Trigger: Calling `ensure_session_id_available(session_id, cwd)` (or the CLI `--session-id` flag it backs) with a string that is not a valid UUID, e.g. a name like 'my-session', a truncated UUID, or one with invalid characters.
Common situations: Typing a descriptive session name instead of a UUID; copying a UUID with extra characters or missing a segment; old configs from a version that accepted arbitrary session-id strings; shell interpolation producing an empty or partial value for `--session-id`.
Related errors
- {CHAT_MODE_FORK_CONFLICT}
- --header can only be used with HTTP or SSE servers.
- A URL is required for {label} servers. Usage: grok mcp add -
- Invalid URL '{url}'. Server URLs must start with http:// or
- Unexpected arguments after the URL: '{args}'. HTTP and SSE s
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/dc9ebeb3df01d54a.
Report an issue: GitHub.