Hmbown/CodeWhale · error · anyhow::Error
external agy credential store {} exceeds the {} byte safety
Error message
external agy credential store {} exceeds the {} byte safety limit What it means
After the SQLite header check, the code stats the granted file and refuses to parse it if metadata.len() exceeds AGY_STATE_DB_LIMIT. The limit is a resource-safety cap: it prevents an attacker-controlled or accidentally huge file from being fed into the SQLite parser. A legitimate state.vscdb is normally far below the cap.
Source
Thrown at crates/tui/src/agy_credentials.rs:108
let mut header = [0u8; 16];
let read = file.read(&mut header).with_context(|| {
format!(
"reading SQLite header of {}",
codewhale_config::quote_os_path(path)
)
})?;
if read < 16 || header[..15] != *b"SQLite format 3" {
bail!(
"external agy credential file {} is not a SQLite database",
codewhale_config::quote_os_path(path)
);
}
file.seek(SeekFrom::Start(0)).ok();
let metadata = file
.metadata()
.with_context(|| format!("statting {}", codewhale_config::quote_os_path(path)))?;
if metadata.len() > AGY_STATE_DB_LIMIT {
bail!(
"external agy credential store {} exceeds the {} byte safety limit",
codewhale_config::quote_os_path(path),
AGY_STATE_DB_LIMIT
);
}
// Pin the file identity: SQLite reopens the path by name, so hold the
// secure handle open across the query and prove the inode did not move.
let pinned = file_identity(&file);
drop(file);
let value = query_oauth_token(path)?;
let reopened = std::fs::File::open(path)
.ok()
.and_then(|recheck| file_identity_of(&recheck));
if pinned != reopened {
bail!(
"external agy credential store {} changed while being read",
codewhale_config::quote_os_path(path)
);View on GitHub (pinned to 0c42157ee5)
Solutions
- Have the Antigravity/IDE client compact the store (close it, then vacuum or let it prune WAL/history) so state.vscdb shrinks below AGY_STATE_DB_LIMIT.
- Check `std::fs::metadata(path)?.len()` against the limit before invoking the import, and surface an actionable message.
- Fix the consent entry so it names the actual credential store rather than a broad path that can match a large unrelated database.
Example fix
// before
let token = antigravity_oauth_token_from_grant(&grant)?; // bails: exceeds safety limit
// after
const AGY_STATE_DB_LIMIT: u64 = 64 * 1024 * 1024; // keep in sync with tui
if std::fs::metadata(grant.path())?.len() > AGY_STATE_DB_LIMIT {
anyhow::bail!("compact the agy state.vscdb (vacuum) before import");
}
let token = antigravity_oauth_token_from_grant(&grant)?; Defensive patterns
Strategy: validation
Validate before calling
const AGY_STATE_DB_LIMIT: u64 = 64 * 1024 * 1024; // keep in sync with crates/tui
let len = std::fs::metadata(grant.path())?.len();
if len > AGY_STATE_DB_LIMIT {
anyhow::bail!("state.vscdb is {len} bytes; compact (vacuum) it before import");
} Try / catch
match antigravity_oauth_token_from_grant(&grant) {
Ok(t) => t,
Err(e) if e.to_string().contains("safety limit") => { /* prompt user to vacuum/close client */ return Err(e) }
Err(e) => return Err(e),
} Prevention
- Close the Antigravity/IDE client and vacuum the profile database periodically.
- Check file size before import and surface the limit number in the error UI.
- Keep the consent entry scoped to the single credential db, not other large databases in the profile.
When it happens
Trigger: antigravity_oauth_token_from_grant on a granted file whose on-disk size is larger than AGY_STATE_DB_LIMIT — e.g. a state.vscdb that grew huge from accumulated IDE history/blob data, or a grant pointed at some other large .db file.
Common situations: Long-lived IDE profiles with un-vacuumed SQLite stores; grants matching a directory of databases by glob so the wrong (large) db is selected; testing against synthetic oversized fixtures.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- external agy credential file {} is not a SQLite database
- Antigravity import requires an agy_cli grant, not {}
- external agy credential store {} changed while being read
- agy OAuth token member `{member}` is empty
- agy OAuth token JSON carries no access token member
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/f8e3c67ac74d1212.
Report an issue: GitHub.