Hmbown/CodeWhale · error
stage setup state
Error message
stage setup state
What it means
This panic comes from `.expect("stage setup state")` on `SetupTransaction::stage_json(&state_path, &SetupState::default())` at crates/config/src/tests.rs:4302. `stage_json` serializes the value to JSON and stages the bytes for atomic application at commit. It fails when `SetupState` cannot be serialized to JSON or the staged path is invalid/unwritable by transaction rules.
Solutions
- Check that the state path's parent is a real directory
- Verify SetupState derives Serialize and every field is JSON-serializable
- Confirm the tempdir is still alive at staging time
Example fix
// before
transaction.stage_json(&state_path, &SetupState::default()).expect("stage setup state");
// after
assert!(state_path.parent().map_or(false, |p| p.is_dir()), "state parent not a directory");
transaction.stage_json(&state_path, &SetupState::default())
.map_err(|e| panic!("stage setup state: {e:#}"))
.unwrap(); Defensive patterns
Strategy: validation
Validate before calling
assert!(state_path.parent().map_or(false, |p| p.is_dir()), "state parent must be a directory");
serde_json::to_vec(&SetupState::default()).map_err(|e| format!("SetupState not serializable: {e}"))?; Prevention
- Keep Serialize derived on SetupState and all its fields
- Stage only paths whose parents exist and are directories
- Test serialization of default values after schema changes
When it happens
Trigger: Staging a `SetupState` value that fails serde JSON serialization, or a `state_path` whose parent directory does not exist or is not a directory (in this test's sibling test, a regular file 'blocker' occupies the parent slot to force failure).
Common situations: A serde rename/skip misconfiguration making a field unserializable; pointing stage_json at a path under a file rather than a directory; a stale path from a removed tempdir.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/4987060efc632f72.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/tests.rs:4302
let config_path = dir.path().join(CONFIG_FILE_NAME);
let state_path = dir.path().join(crate::setup_state::SETUP_STATE_FILE_NAME);
fs::write(
&config_path,
"# my model\nmodel = \"deepseek-v4-flash\"\n# end comment\n",
)
.expect("write config");
let mut store = ConfigStore::load(Some(config_path.clone())).expect("load config store");
store.config.model = Some("deepseek-v4-pro".to_string());
let mut transaction = persistence::SetupTransaction::new();
transaction.stage(
&config_path,
store.rendered_body().expect("rendered body").into_bytes(),
);
transaction
.stage_json(&state_path, &SetupState::default())
.expect("stage setup state");
transaction.commit().expect("commit");
let body = fs::read_to_string(&config_path).expect("read config");
assert!(body.contains("# my model"), "prefix comment preserved");
assert!(body.contains("# end comment"), "suffix comment preserved");
assert!(body.contains("model = \"deepseek-v4-pro\""));
assert!(state_path.exists(), "sibling setup state written");
}
#[test]
fn setup_transaction_rolls_back_config_store_body_on_sibling_failure() {
// #3410 rollback expectation: when a sibling stage fails to apply, the
// already-written config.toml is restored byte-for-byte, comments and
// all — no half-applied setup.
let dir = tempfile::tempdir().expect("tempdir");
let config_path = dir.path().join(CONFIG_FILE_NAME);
let original = "# my model\nmodel = \"deepseek-v4-flash\"\n# end comment\n";
fs::write(&config_path, original).expect("write config");View on GitHub (pinned to 433685b202)