sigoden/aichat · error · anyhow::Error

No application_default_credentials.json

Error message

No application_default_credentials.json

What it means

In src/client/vertexai.rs `load_adc`, no Application Default Credentials file could be located: the explicit `file` option was None and `default_adc_file()` (which probes `~/.config/gcloud/application_default_credentials.json` and platform equivalents) found nothing. The library throws this instead of attempting token refresh without credentials.

Solutions

  1. Run `gcloud auth application-default login` to create the default ADC file.
  2. Point the client's ADC `file` config option at an existing credentials JSON.
  3. Verify `default_adc_file`'s expected location exists (check $HOME/.config/gcloud/ on Linux/macOS, %APPDATA%/gcloud on Windows).
  4. In CI, generate ADC via a service account key and set GOOGLE_APPLICATION_CREDENTIALS-style path in config.

Example fix

// before (no credentials)
Error: No application_default_credentials.json

// after
gcloud auth application-default login
Defensive patterns

Strategy: validation

Validate before calling

// Shell guard before invoking the tool
test -f "$HOME/.config/gcloud/application_default_credentials.json" \
  || { echo 'run: gcloud auth application-default login'; exit 1; }

Try / catch

// Rust
match run_vertexai().await {
    Err(e) if e.to_string().contains("application_default_credentials.json") => {
    // prompt user to run gcloud auth application-default login
    }
    other => other?,
}

Prevention

When it happens

Trigger: Using the Vertex AI provider without an ADC file on disk and without a `file` path configured for ADC, so `.or_else(default_adc_file)` yields None.

Common situations: Fresh machine or CI container where `gcloud auth application-default login` was never run; running as a different user so $HOME points elsewhere; GCP_ADC_FILE-style config path typo.

Related errors


AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/23c0bb8442129311. Report an issue: GitHub.

Appendix: source

Thrown at src/client/vertexai.rs:496

        .await?;

    if let (Some(access_token), Some(expires_in)) =
        (value["access_token"].as_str(), value["expires_in"].as_i64())
    {
        Ok((access_token.to_string(), expires_in))
    } else if let Some(err_msg) = value["error_description"].as_str() {
        bail!("{err_msg}")
    } else {
        bail!("Invalid response data: {value}")
    }
}

async fn load_adc(file: &Option<String>) -> Result<Value> {
    let adc_file = file
        .as_ref()
        .map(PathBuf::from)
        .or_else(default_adc_file)
        .ok_or_else(|| anyhow!("No application_default_credentials.json"))?;
    let data = tokio::fs::read_to_string(adc_file).await?;
    let data: Value = serde_json::from_str(&data)?;
    if let (Some(client_id), Some(client_secret), Some(refresh_token)) = (
        data["client_id"].as_str(),
        data["client_secret"].as_str(),
        data["refresh_token"].as_str(),
    ) {
        Ok(json!({
            "client_id": client_id,
            "client_secret": client_secret,
            "refresh_token": refresh_token,
            "grant_type": "refresh_token",
        }))
    } else {
        bail!("Invalid application_default_credentials.json")
    }
}

View on GitHub (pinned to 82976d349a)