{"record":{"id":"9634da7e77a64e2b","repo":"Hmbown/CodeWhale","slug":"fleet-task-has-an-invalid-durable-member-snapshot-error","errorCode":null,"errorMessage":"Fleet task {} has an invalid durable member snapshot: {error}","messagePattern":"Fleet task (.+?) has an invalid durable member snapshot: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/worker_runtime.rs","lineNumber":978,"sourceCode":"    provider: Option<&str>,\n) -> bool {\n    let requested = requested.trim();\n    let model = model.trim();\n    requested == model\n        || provider\n            .and_then(non_empty_trimmed)\n            .and_then(|provider| requested.strip_prefix(&format!(\"{provider}/\")))\n            .is_some_and(|requested_model| requested_model == model)\n}\n\nfn resolve_task_agent_profile<'a>(\n    task_spec: &FleetTaskSpec,\n    agent_profiles: &'a [AgentProfile],\n) -> Result<Option<Cow<'a, AgentProfile>>> {\n    if let Some(snapshot) = task_spec.metadata.get(FROZEN_FLEET_MEMBER_METADATA_KEY) {\n        let snapshot: FrozenFleetMember =\n            serde_json::from_value(snapshot.clone()).map_err(|error| {\n                anyhow::anyhow!(\n                    \"Fleet task {} has an invalid durable member snapshot: {error}\",\n                    task_spec.id\n                )\n            })?;\n        return Ok(Some(Cow::Owned(snapshot.into_profile()?)));\n    }\n    let Some(worker) = task_spec.worker.as_ref() else {\n        return Ok(None);\n    };\n    if let Some(selector) = worker\n        .agent_profile\n        .as_deref()\n        .map(str::trim)\n        .filter(|selector| !selector.is_empty())\n    {\n        let profile = resolve_member_in_profiles(agent_profiles, selector).map_err(|error| {\n            anyhow::anyhow!(\n                \"Fleet task {} has invalid worker.agent_profile selector {selector:?}: {error}\",","sourceCodeStart":960,"sourceCodeEnd":996,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/fleet/worker_runtime.rs#L960-L996","documentation":"Thrown by resolve_task_agent_profile when a Fleet task's metadata contains a durable frozen-member snapshot under FROZEN_FLEET_MEMBER_METADATA_KEY, but the stored serde_json::Value cannot deserialize into FrozenFleetMember. Because this snapshot is the durable record of which profile a worker uses, an invalid snapshot is refused rather than silently ignored, keeping frozen membership stable across roster edits.","triggerScenarios":"Resolving a task's agent profile (via validate_task_agent_profiles, fleet_task_to_worker_spec_with_profiles, resolve_fleet_route_*) when its metadata JSON was hand-edited, written by an older/other version with a different snapshot schema, or corrupted in the ledger.","commonSituations":"Manual metadata edits in the ledger/task store; schema change between Codewhale versions so old snapshots no longer match FrozenFleetMember; partial JSON write during a crash.","solutions":["Fix or regenerate the snapshot: re-freeze the task (re-run the freeze path) so metadata is rewritten from a valid roster.","Delete the FROZEN_FLEET_MEMBER_METADATA_KEY entry and set worker.agent_profile explicitly so resolution falls back to selector-based lookup.","Restore the task/ledger record from backup if it was corrupted.","If snapshots come from an older version, migrate or drop them before running the new validator."],"exampleFix":"// before: hand-edited metadata\n{\"frozen_member\": {\"profile\": \"reviewer\"}}\n// after: remove and let freeze rewrite it\n{} // then set worker.agent_profile = \"reviewer\"","handlingStrategy":"validation","validationCode":"// Rust\nif let Some(v) = task_spec.metadata.get(FROZEN_FLEET_MEMBER_METADATA_KEY) {\n    if let Err(e) = serde_json::from_value::<FrozenFleetMember>(v.clone()) {\n        eprintln!(\"corrupt snapshot on task {}: {e}\", task_spec.id);\n    }\n}","typeGuard":null,"tryCatchPattern":"// Rust\nmatch resolve_task_agent_profile(&task_spec, &profiles) {\n    Err(e) if e.to_string().contains(\"invalid durable member snapshot\") => {\n        log::warn!(\"task {} needs re-freeze\", task_spec.id);\n    }\n    other => other?,\n}","preventionTips":["Never hand-edit task metadata JSON; re-freeze through the tool instead.","After a version upgrade, run the validators once to surface snapshot schema drift.","Back up ledger/task storage before edits so snapshots can be restored."],"tags":["serde","json","fleet","deserialization"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}