Hmbown/CodeWhale · error
could not snapshot the Codewhale-owned legacy
Error message
could not snapshot the Codewhale-owned legacy {slot} secret slot before clearing it: {error}; config was not changed What it means
clear_legacy_antigravity_config migrates away from the legacy Antigravity provider config. Before changing anything it snapshots the existing secret slot via secrets.get(slot); if that read fails, it aborts the whole migration with this message so the config is left untouched. This is a safety checkpoint: never clear a secret you could not first read back.
Solutions
- Ensure the OS secret service/keyring is running and unlocked, then retry the migration
- Unlock the keychain or grant the CLI access to the slot if access control blocked the read
- Fix or reset the secret backend; verify `secrets.get` works for the slot
- Skip/defer the legacy migration until the backend is healthy — config remains unchanged
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: verify the slot is readable before triggering the migration
let probe = secrets.get(provider_slot(ProviderKind::Antigravity));
if probe.is_err() { eprintln!("secret backend unavailable; defer legacy cleanup"); } Try / catch
match clear_legacy_antigravity_config(store, secrets) {
Err(e) if e.to_string().contains("snapshot") => {
eprintln!("secret store unreadable — config left unchanged; fix keyring and retry");
}
other => other?,
} Prevention
- Ensure the keyring/secret service is running and unlocked before running migrations
- Run migrations interactively the first time so keychain access prompts can be approved
- Monitor secret-backend health on headless hosts where migrations run unattended
When it happens
Trigger: `secrets.get(slot)` for the Antigravity slot returns Err — the secret backend (keyring/OS agent) is unavailable, locked, or returns an IO error during the legacy-config cleanup migration.
Common situations: Running the legacy migration on a headless machine without a keyring service, a locked keychain prompting for access, or a corrupted secret store entry.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- could not clear the Codewhale-owned legacy
- Codewhale account login requires an OS credential manager…
- ; additionally could not verify rollback of the…
- ; additionally failed to restore prior secret-store state…
- Secret storage failed: . Refusing to write the API key in…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/5bfd9a2da41ba725.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/lib.rs:2688
println!("cleared xAI credentials from config, secret store, and owned OAuth storage");
} else {
println!("cleared API key for {slot} from config and secret store");
}
Ok(())
}
/// Remove only Codewhale-owned state for the retired Antigravity route.
///
/// This deliberately operates on the already-loaded Codewhale config and its
/// own secret slot. It never resolves an external credential path, reads an
/// environment credential, or invokes a Google/Antigravity logout or revoke
/// flow.
fn clear_legacy_antigravity_config(store: &mut ConfigStore, secrets: &Secrets) -> Result<()> {
let provider = ProviderKind::Antigravity;
let slot = provider_slot(provider);
let original_config = store.config.clone();
let prior_secret = secrets.get(slot).map_err(|error| {
anyhow!(
"could not snapshot the Codewhale-owned legacy {slot} secret slot before clearing it: {error}; config was not changed"
)
})?;
store.config.providers.antigravity = Default::default();
store
.config
.fallback_providers
.retain(|fallback| *fallback != provider);
if store.config.provider == provider {
store.config.provider = ProviderKind::default();
store.config.selected_provider_id = None;
}
if let Err(error) = secrets.delete(slot) {
store.config = original_config;
return Err(anyhow!(
"could not clear the Codewhale-owned legacy {slot} secret slot: {error}; config was not changed"View on GitHub (pinned to 73e0f67d83)