xai-org/grok-build · error · io::Error

Writeback storage mode requires authentication. Run 'grok lo

Error message

Writeback storage mode requires authentication. Run 'grok login' first.

What it means

Configuring StorageMode::Writeback (local writes with remote sync-back) requires an AuthManager to obtain credentials for RemoteSync; when none was provided, setup fails fast with io::ErrorKind::PermissionDenied instead of silently running unauthenticated. The message points the user at 'grok login'.

Source

Thrown at crates/codegen/xai-grok-shell/src/session/persistence.rs:2415

        if let SessionUpdate::Acp(notification) = update {
            remote_sync.queue(*notification);
            backfilled += 1;
        }
    }
    remote_sync.flush();
    backfilled
}

fn init_remote_sync(
    summary: &Summary,
    storage_mode: StorageMode,
    auth_manager: Option<Arc<crate::auth::AuthManager>>,
) -> io::Result<Option<RemoteSync>> {
    match storage_mode {
        StorageMode::Local => Ok(None),
        StorageMode::Writeback => {
            let auth_manager = auth_manager.ok_or_else(|| {
                io::Error::new(
                    io::ErrorKind::PermissionDenied,
                    "Writeback storage mode requires authentication. Run 'grok login' first.",
                )
            })?;
            if let Some(auth) = auth_manager.current_or_expired() {
                if auth.is_zdr_team() {
                    tracing::debug!("ZDR team: skipping remote sync");
                    return Ok(None);
                }
            } else {
                tracing::warn!(
                    "writeback: no auth loaded yet, ZDR check skipped (backend enforces server-side)"
                );
            }
            tracing::info!("Writeback mode enabled, syncing to backend");
            let client =
                crate::remote::BackendClient::new().with_auth_manager(auth_manager.clone());
            let metadata = ExportedMetadata::from_summary(summary);

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Run 'grok login' to create credentials, then retry
  2. Pass an AuthManager instance when constructing the session if you build it programmatically
  3. Switch storage_mode to Local if remote sync is not needed
  4. Fix environment (HOME/XDG config paths, mounted credentials) so the auth manager can be created

Example fix

// before
let session = Session::builder().storage_mode(StorageMode::Writeback).build()?;
// after
let session = Session::builder()
    .storage_mode(StorageMode::Writeback)
    .auth_manager(Some(AuthManager::load()?))
    .build()?;
// or run: grok login
Defensive patterns

Strategy: validation

Validate before calling

if storage_mode == StorageMode::Writeback && auth_manager.is_none() {
    bail!("Writeback mode needs auth: run `grok login` or pass an AuthManager");
}

Type guard

fn writeback_auth_ready(mode: StorageMode, auth: &Option<Arc<AuthManager>>) -> bool {
    mode != StorageMode::Writeback || auth.is_some()
}

Try / catch

match Session::open(cfg).await {
    Err(e) if e.kind() == io::ErrorKind::PermissionDenied && e.to_string().contains("grok login") => {
        run_login_flow()?;
        Session::open(cfg).await?
    }
    other => other?,
}

Prevention

When it happens

Trigger: Starting a session with storage_mode = StorageMode::Writeback while the auth_manager parameter is None — i.e. no credentials source configured for remote sync.

Common situations: Fresh install where 'grok login' was never run; CI/container environment with no persisted auth; running with a config that forces Writeback while auth is disabled/omitted; HOME/config dir not writable so stored credentials are invisible.

Understand the failure class

Related errors


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