xai-org/grok-build · warning · DeviceCodeError

NotEnabled

NotEnabled

Error message

Device-code login is not available for this deployment. Try `grok login` or set XAI_API_KEY instead.

What it means

request_device_code POSTs to the deployment's device-code endpoint to start device-code login. If the server answers HTTP 404, the endpoint is not deployed/enabled for this deployment, so the typed DeviceCodeError::NotEnabled is raised with this user-facing message suggesting alternatives. Other non-success statuses take the generic HTTP-error path (error 219).

Source

Thrown at crates/codegen/xai-grok-shell/src/auth/device_code.rs:164

            .header("x-grok-client-version", xai_grok_version::VERSION)
            // Lets oauth2-provider separate human-completable logins from
            // headless automation in the device-flow funnel metrics.
            .header("x-grok-client-surface", surface.as_str())
            .form(&[
                ("client_id", client_id),
                ("scope", scope_str.as_str()),
                ("referrer", "grok-build"),
            ]),
        &url,
    )
    .send()
    .await?;

    if !resp.status().is_success() {
        let status = resp.status();
        let body = resp.text().await.unwrap_or_default();
        if status.as_u16() == 404 {
            anyhow::bail!(DeviceCodeError::NotEnabled);
        }
        anyhow::bail!("Device code request failed (HTTP {status}): {body}");
    }

    let server_resp: DeviceCodeResponse = resp.json().await?;

    // Defend against control characters from a malicious issuer.
    if !server_resp
        .user_code
        .chars()
        .all(|c| c.is_ascii_alphanumeric() || c == '-')
    {
        anyhow::bail!("Server returned invalid user_code format (expected [A-Z0-9-])");
    }

    validate_verification_uri(&server_resp.verification_uri)?;
    if let Some(ref verification_uri_complete) = server_resp.verification_uri_complete {
        validate_verification_uri(verification_uri_complete)?;

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Use `grok login` (interactive) instead of device-code flow
  2. Set XAI_API_KEY in the environment and skip device login entirely
  3. Confirm the deployment actually supports device-code login (check server version/config)
  4. Verify the auth base URL configured for the client points at the correct deployment

Example fix

// before
grok login --device-code
// after
export XAI_API_KEY=xai-...
grok login  # or rely on env key
Defensive patterns

Strategy: fallback

Validate before calling

// Probe whether the deployment supports device-code login
let probe = client.post(device_code_url).send().await?;
if probe.status() == reqwest::StatusCode::NOT_FOUND {
    eprintln!("device-code login disabled here; use API key");
}

Try / catch

match request_device_code(&client, &cfg).await {
    Ok(dc) => dc,
    Err(e) if matches!(*e.downcast::<DeviceCodeError>().unwrap_or_default(), DeviceCodeError::NotEnabled) => {
        eprintln!("falling back to `grok login` / XAI_API_KEY");
        fallback_login().await?
    },
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling run_device_code_login_channels -> request_device_code when the auth server returns 404 for the device-code initiation request, meaning the deployment disabled or never deployed device-code login.

Common situations: Self-hosted or enterprise deployments without the device-code route, API gateway path rewrites dropping the endpoint, hitting the wrong base URL (e.g. staging config against production), or server version older than the endpoint.

Related errors


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