Hmbown/CodeWhale · error
rotate fixture
Error message
rotate fixture
What it means
A panic from `std::fs::write(...).expect("rotate fixture")` — writing the rotated (account-B) auth.json failed. Same failure modes as the initial fixture write: permissions, missing directory, or full disk. It occurs after the client was already constructed, so only the rotation-phase write is affected.
Solutions
- Check free space and write access on the temp volume; probe with touch.
- Disable tmp cleaners that race with the test (systemd-tmpfiles, tmpwatch).
- Re-run with a fresh dedicated TMPDIR (mktemp -d) outside swept paths.
- In containers, mount the temp dir as writable tmpfs and confirm ownership.
Defensive patterns
Strategy: validation
Validate before calling
// rust, before the rotation write assert!(path.parent().map(|d| d.is_dir()).unwrap_or(false), "fixture dir gone before rotation");
Try / catch
std::fs::write(&path, rotated)
.unwrap_or_else(|e| panic!("rotate fixture {path:?}: {e}")); Prevention
- Same preflight as the initial write: writable temp volume, no cleaner races.
- Re-check free space before multi-write tests on small CI disks.
- Keep TempDir alive through the entire test body.
When it happens
Trigger: `std::fs::write(&path, rotated_json).expect("rotate fixture")` fails on the canonicalized tempdir path mid-test (ENOENT after cleaner sweep, EACCES, ENOSPC).
Common situations: Tmp cleaner deleting the fixture directory mid-test, read-only temp mounts in CI containers, or disk exhaustion between the first and second write.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/df25e7588f668c3c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:8303
};
crate::external_credentials::reset_side_effect_trap();
let client = CodewhaleClient::new(&config).expect("Codex client");
assert_eq!(client.api_key, token_a);
assert_eq!(client.codex_account_id.as_deref(), Some("account-a"));
assert_eq!(
crate::external_credentials::side_effect_trap_counts(),
(1, 1),
"bearer and account id must come from one secure open/read"
);
// An owner rotation after construction cannot splice account B into
// the already-resolved bearer snapshot.
std::fs::write(
&path,
serde_json::to_string(&serde_json::json!({"tokens": {"access_token": crate::test_support::future_test_jwt("b"), "account_id": "account-b"}})).expect("serialize rotated fixture"),
)
.expect("rotate fixture");
assert_eq!(client.api_key, token_a);
assert_eq!(client.codex_account_id.as_deref(), Some("account-a"));
}
fn client_with_config_secret_sentinels() -> CodewhaleClient {
let _ = rustls::crypto::ring::default_provider().install_default();
CodewhaleClient::new(&Config {
provider: Some("zai".to_string()),
api_key: Some(CONFIG_SECRET_SENTINELS[0].to_string()),
providers: Some(ProvidersConfig {
arcee: ProviderConfig {
api_key: Some(CONFIG_SECRET_SENTINELS[1].to_string()),
..ProviderConfig::default()
},
moonshot: ProviderConfig {
api_key: Some(CONFIG_SECRET_SENTINELS[2].to_string()),
..ProviderConfig::default()
},View on GitHub (pinned to 73e0f67d83)