{"record":{"id":"3862f358869afa9c","repo":"Hmbown/CodeWhale","slug":"codewhale-owned-credential-file-exceeds-the","errorCode":null,"errorMessage":"Codewhale-owned credential file {} exceeds the {} byte safety limit","messagePattern":"Codewhale-owned credential file (.+?) exceeds the (.+?) byte safety limit","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/external_credentials.rs","lineNumber":138,"sourceCode":"                format!(\n                    \"securely opening Codewhale-owned credential file {}\",\n                    codewhale_config::quote_os_path(path)\n                )\n            });\n        }\n    };\n    let mut bytes = Vec::new();\n    file.by_ref()\n        .take(MAX_EXTERNAL_CREDENTIAL_BYTES + 1)\n        .read_to_end(&mut bytes)\n        .with_context(|| {\n            format!(\n                \"reading Codewhale-owned credential file {}\",\n                codewhale_config::quote_os_path(path)\n            )\n        })?;\n    if bytes.len() as u64 > MAX_EXTERNAL_CREDENTIAL_BYTES {\n        bail!(\n            \"Codewhale-owned credential file {} exceeds the {} byte safety limit\",\n            codewhale_config::quote_os_path(path),\n            MAX_EXTERNAL_CREDENTIAL_BYTES\n        );\n    }\n    String::from_utf8(bytes).map(Some).with_context(|| {\n        format!(\n            \"Codewhale-owned credential file {} is not valid UTF-8\",\n            codewhale_config::quote_os_path(path)\n        )\n    })\n}\n\n#[cfg(unix)]\nfn open_secure_regular_file(path: &Path, require_owner_only: bool) -> io::Result<File> {\n    use std::ffi::CString;\n    use std::os::fd::FromRawFd;\n    use std::os::unix::ffi::OsStrExt;","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/external_credentials.rs#L120-L156","documentation":"Codewhale refuses to load a Codewhale-owned credential file larger than MAX_EXTERNAL_CREDENTIAL_BYTES (1 MiB, defined in crates/tui/src/external_credentials.rs:18). The reader takes at most limit+1 bytes, so any file over the limit is detected without reading it fully. The guard exists because a multi-megabyte 'credential' almost always means the path points at the wrong file (a JSON dump, a keychain export, a log), not a token.","triggerScenarios":"Calling the external-credential loader with a Codewhale-owned credential path whose file size exceeds 1 MiB: e.g. a credential file that was overwritten with a full API response, a certificate bundle, or a symlink to a large file.","commonSituations":"Pointing the credential setting at an oauth token JSON that embeds a refresh cookie jar; accidentally saving the provider's entire /credentials endpoint response instead of just the token; a rotated file that appends instead of truncating.","solutions":["Inspect the file size and head bytes (ls -l, head -c 200) to confirm it is not actually a raw credential","Re-create the file containing only the credential value (printf '%s' \"$TOKEN\" > file), no trailing newline dump or JSON wrapper unless the loader expects it","Check the configured path in settings for typos or a wrong symlink target","If a legitimate credential genuinely exceeds 1 MiB, raise MAX_EXTERNAL_CREDENTIAL_BYTES and rebuild, but treat this as a red flag first"],"exampleFix":"# before\n$ ls -l ~/.config/codewhale/credentials/provider.token\n-rw-r--r-- 1 user user 48210311 ...  # wrong file\n\n# after\n$ printf '%s' \"$PROVIDER_TOKEN\" > ~/.config/codewhale/credentials/provider.token\n$ ls -l ~/.config/codewhale/credentials/provider.token\n-rw-r--r-- 1 user user 217 ...","handlingStrategy":"validation","validationCode":"use std::fs;\n\nconst MAX_EXTERNAL_CREDENTIAL_BYTES: u64 = 1024 * 1024;\n\nfn credential_file_size_ok(path: &std::path::Path) -> bool {\n    fs::metadata(path)\n        .map(|m| m.len() <= MAX_EXTERNAL_CREDENTIAL_BYTES)\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"if let Err(err) = load_credential(&path) {\n    if err.to_string().contains(\"exceeds the\") {\n        eprintln!(\"credential file too large; check {} for the wrong file\", path.display());\n    }\n    return Err(err);\n}","preventionTips":["Write credential files with printf '%s' \"$TOKEN\" instead of echoing API responses into them","Alert when a credential file grows past a few KiB; tokens are small","Never point the credential setting at directory listing dumps or keychain exports"],"tags":["credentials","file-size-limit","configuration","rust","codewhale"],"backgroundTag":"config-file-limit-exceeded","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}