xai-org/grok-build · error

Headless mode requires a grok.com session. Run `grok login`

Error message

Headless mode requires a grok.com session. Run `grok login` to sign in, or use `grok agent stdio` for API-key access.

What it means

run_headless requires an authenticated grok.com session. Before starting headless mode, if an XAI API key env var is present and no auth-provider command is set, the code tries try_ensure_fresh_auth; if that returns None (no valid/fresh stored credentials), it bails with HEADLESS_NO_SESSION telling the user to run `grok login` or use `grok agent stdio` with an API key.

Source

Thrown at crates/codegen/xai-grok-shell/src/agent/app.rs:365

    let (mut auth, did_browser_flow) = if reauthenticate {
        let auth_manager = Arc::new(AuthManager::new(&grok_home::grok_home(), ctx.clone()));
        run_auth_flow(
            &auth_manager,
            ctx,
            true,
            None,
            None,
            None,
            crate::auth::LoginTransportOverride::None,
        )
        .await?
    } else {
        let auth_manager = Arc::new(AuthManager::new(&grok_home::grok_home(), ctx.clone()));
        if crate::agent::auth_method::has_xai_api_key_env()
            && ctx.auth_provider_command.is_none()
            && crate::auth::try_ensure_fresh_auth(ctx).await.is_none()
        {
            anyhow::bail!("{HEADLESS_NO_SESSION}");
        }
        run_auth_flow(
            &auth_manager,
            ctx,
            false,
            None,
            None,
            None,
            crate::auth::LoginTransportOverride::None,
        )
        .await?
    };
    if auth.user_id.is_empty() || auth.email.is_none() {
        auth = Arc::new(agent_config.create_auth_manager())
            .update(auth.clone())
            .await?;
    }
    let auth_for_prefetch = auth.clone();

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Run `grok login` interactively to establish the grok.com session, then retry headless mode.
  2. Use `grok agent stdio` instead, which supports API-key access without a grok.com session.
  3. Ensure the auth state (grok home directory) is mounted/copied into CI or container environments.
  4. Re-authenticate if the stored session expired (credentials exist but are stale).

Example fix

// before (CI script)
grok agent --headless ...
// after
grok login  # once, interactively, to seed credentials
grok agent --headless ...
# or, without a session:
grok agent stdio  # API-key access
Defensive patterns

Strategy: validation

Validate before calling

// before invoking headless mode, check a session exists
fn headless_ready() -> bool {
    grok_home::has_session_credentials() // stored grok.com auth present
}

Try / catch

match app::run_headless(ctx).await {
    Err(e) if e.to_string().contains("requires a grok.com session") => {
        eprintln!("No session. Run `grok login` first, or use `grok agent stdio`.");
        std::process::exit(2);
    }
    other => other,
}

Prevention

When it happens

Trigger: Running headless mode with no stored grok.com session credentials: try_ensure_fresh_auth(ctx) returned None while has_xai_api_key_env() was true and ctx.auth_provider_command was None.

Common situations: Fresh machine or CI container where `grok login` was never run; expired/revoked session token; running headless in an environment without the stored auth state directory; user assumed the API key env var alone was enough for headless relay usage.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/832a61a58dd803f0. Report an issue: GitHub.