{"record":{"id":"5fd43e1302eec17f","repo":"googleworkspace/cli","slug":"google-workspace-cli-credentials-file-points-to-p","errorCode":null,"errorMessage":"GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE points to {path}, but file does not exist","messagePattern":"GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE points to (.+?), but file does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/google-workspace-cli/src/auth.rs","lineNumber":349,"sourceCode":"        })?;\n    Ok(Credential::AuthorizedUser(secret))\n}\n\nasync fn load_credentials_inner(\n    env_file: Option<&str>,\n    enc_path: &std::path::Path,\n    default_path: &std::path::Path,\n) -> anyhow::Result<Credential> {\n    // 1. Explicit env var — plaintext file (User or Service Account)\n    if let Some(path) = env_file {\n        let p = PathBuf::from(path);\n        if p.exists() {\n            let content = tokio::fs::read_to_string(&p)\n                .await\n                .with_context(|| format!(\"Failed to read credentials from {path}\"))?;\n            return parse_credential_file(&p, &content).await;\n        }\n        anyhow::bail!(\n            \"GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE points to {path}, but file does not exist\"\n        );\n    }\n\n    // 2. Encrypted credentials\n    if enc_path.exists() {\n        match credential_store::load_encrypted_from_path(enc_path) {\n            Ok(json_str) => {\n                return parse_credential_file(enc_path, &json_str).await;\n            }\n            Err(e) => {\n                // Decryption failed — the encryption key likely changed (e.g. after\n                // an upgrade that migrated keys between keyring and file storage).\n                // Remove the stale file so the next `gws auth login` starts fresh,\n                // and fall through to other credential sources (plaintext, ADC).\n                eprintln!(\n                    \"Warning: removing undecryptable credentials file ({}): {e:#}\",\n                    enc_path.display()","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/googleworkspace/cli/blob/a3768d0e82ad83cca2da97724e46bea4ff0e6dbd/crates/google-workspace-cli/src/auth.rs#L331-L367","documentation":"During credential resolution, step 1 honors GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE as an explicit plaintext credential path (authorized_user or service_account JSON). Because the variable is explicitly set, a missing file is a hard error rather than a silent fallthrough — the CLI refuses to silently continue with weaker credentials than the operator asked for.","triggerScenarios":"Typo in the path; relative path resolved against an unexpected working directory; '~/creds.json' written inside a .env file (dotenvy does not expand ~); file deleted or never created; wrong shell quoting in CI.","commonSituations":"CI job sets the variable via a secret that references a path not present in the runner image; a .env entry uses a tilde or unexpanded $HOME; the credential file is gitignored and missing after a fresh clone; docker-compose env lacks the mounted volume containing the file.","solutions":["Echo the variable and run `ls -la` on the exact value to see what the shell actually resolves","Use an absolute path (e.g. /home/user/creds.json or /run/secrets/creds.json) — not ~ or a relative path","In .env files, expand manually: GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/home/user/creds.json","If the file was never intended as plaintext, unset the variable and use `gws auth login` encrypted credentials instead"],"exampleFix":"# before (.env — tilde is NOT expanded by dotenvy)\nGOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=~/gcp/creds.json\n\n# after\nGOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/home/youruser/gcp/creds.json","handlingStrategy":"validation","validationCode":"// Run before invoking gws / the credential resolver\nif let Ok(p) = std::env::var(\"GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE\") {\n    let path = std::path::Path::new(&p);\n    assert!(path.is_file(), \"GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE={p} does not exist — use an absolute path\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use absolute paths in env files and CI variables — tilde and $HOME are not expanded by dotenvy","Add a startup assertion (or script check) that the credentials file exists before long-running jobs start","Prefer secret mounts (/run/secrets/...) over paths inside the image for containers"],"tags":["credentials","env-var","config","path"],"backgroundTag":"credentials-file-not-found","analyzedSha":"a3768d0e82ad83cca2da97724e46bea4ff0e6dbd","analyzedAt":"2026-08-16T19:51:46.516Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}