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

  1. 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.
  2. Check `std::fs::metadata(path)?.len()` against the limit before invoking the import, and surface an actionable message.
  3. 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

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


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/f8e3c67ac74d1212. Report an issue: GitHub.