{"record":{"id":"2286c41ad885ea95","repo":"googleworkspace/cli","slug":"cannot-read-e","errorCode":null,"errorMessage":"Cannot read {}: {e}","messagePattern":"Cannot read (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/google-workspace-cli/src/oauth_config.rs","lineNumber":94,"sourceCode":"    };\n\n    let path = client_config_path();\n    if let Some(parent) = path.parent() {\n        std::fs::create_dir_all(parent)?;\n    }\n\n    let json = serde_json::to_string_pretty(&config)?;\n    crate::fs_util::atomic_write(&path, json.as_bytes())\n        .map_err(|e| anyhow::anyhow!(\"Failed to write client config: {e}\"))?;\n\n    Ok(path)\n}\n\n/// Loads OAuth client configuration from the standard Google Cloud Console format.\npub fn load_client_config() -> anyhow::Result<InstalledConfig> {\n    let path = client_config_path();\n    let data = std::fs::read_to_string(&path)\n        .map_err(|e| anyhow::anyhow!(\"Cannot read {}: {e}\", path.display()))?;\n    let file: ClientSecretFile = serde_json::from_str(&data)\n        .map_err(|e| anyhow::anyhow!(\"Invalid client_secret.json format: {e}\"))?;\n    Ok(file.installed)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_save_load_round_trip() {\n        let dir = tempfile::tempdir().unwrap();\n        let path = dir.path().join(\"client_secret.json\");\n\n        let config = ClientSecretFile {\n            installed: InstalledConfig {\n                client_id: \"test-id.apps.googleusercontent.com\".to_string(),\n                client_secret: \"GOCSPX-test\".to_string(),","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/googleworkspace/cli/blob/a3768d0e82ad83cca2da97724e46bea4ff0e6dbd/crates/google-workspace-cli/src/oauth_config.rs#L76-L112","documentation":"`load_client_config()` failed to read `<config dir>/client_secret.json` with `std::fs::read_to_string`. The error names the exact path tried. Overwhelmingly this is NotFound — the user has not completed OAuth client setup yet — but it can also be permission-denied on the file or a directory in the path.","triggerScenarios":"Running `gws auth login` on a fresh machine before `gws auth setup` saved a client config; `GOOGLE_WORKSPACE_CLI_CONFIG_DIR` pointing at a different directory than the one the config was saved in; the file having 000/root-only permissions; passing a credentials file via env var but expecting this loader to find it (it only reads the fixed path).","commonSituations":"New installs that skip the setup wizard; multi-account setups where the config dir was switched; shared machines where another user's umask locked the file; CI with a clean HOME.","solutions":["Run `gws auth setup` (or `gws auth login` interactively) so a client_secret.json is saved, or copy your existing one to the path shown in the error.","Verify the path: `ls -l <path-from-error>` — if it's not where your secret lives, set `GOOGLE_WORKSPACE_CLI_CONFIG_DIR` to the right directory.","Fix permissions (`chmod 600`, correct owner) if the file exists but is unreadable.","Alternatively skip the file entirely: export GOOGLE_WORKSPACE_CLI_CLIENT_ID / GOOGLE_WORKSPACE_CLI_CLIENT_SECRET, or GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE pointing at the downloaded secret."],"exampleFix":"# before\ngws auth login\n# -> Cannot read /home/me/.config/gws/client_secret.json: No such file or directory\n\n# after — put the downloaded Desktop-app secret where the loader looks\ngws auth setup   # interactive wizard writes it\n# or manually:\nmkdir -p ~/.config/gws && cp ~/Downloads/client_secret_*.json ~/.config/gws/client_secret.json\ngws auth login","handlingStrategy":"validation","validationCode":"// Check before attempting an authenticated flow\nlet cfg = gws::oauth_config::client_config_path();\nif !cfg.exists() {\n    eprintln!(\"no client config at {} — run `gws auth setup` first\", cfg.display());\n}","typeGuard":null,"tryCatchPattern":"match load_client_config() {\n    Ok(c) => c,\n    Err(e) if e.to_string().contains(\"Cannot read\") => {\n        eprintln!(\"client_secret.json missing/unreadable — run `gws auth setup`, copy one in, or set GOOGLE_WORKSPACE_CLI_CLIENT_ID/SECRET\");\n        std::process::exit(2);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Complete `gws auth setup` as part of workstation provisioning, before any scripted gws calls.","Keep client_secret.json in your dotfiles/vault and restore it alongside other configs on new machines.","For ephemeral environments, prefer env-var credentials over file-based config."],"tags":["oauth","config-file","file-not-found","auth","setup"],"backgroundTag":"config-file-not-found","analyzedSha":"a3768d0e82ad83cca2da97724e46bea4ff0e6dbd","analyzedAt":"2026-08-16T19:51:46.516Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}