{"record":{"id":"931c41ff919b6e31","repo":"Hmbown/CodeWhale","slug":"write-capable-sub-agent-launch-requires-a-durable","errorCode":null,"errorMessage":"write-capable sub-agent launch requires a durable coordination state path","messagePattern":"write-capable sub-agent launch requires a durable coordination state path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":6353,"sourceCode":"                    &tool_profile,\n                    &agent.model,\n                    options.model_route.clone(),\n                    options.write_claim.is_some(),\n                );\n                runtime.worker_profile = profile.clone();\n                profile\n            }\n        };\n        let write_capable = runtime_profile.permissions.write;\n        if write_capable {\n            // Isolated-worktree children mutate their own checkout, so they\n            // do not contend for the shared-workspace process lock (#5036).\n            if !options.isolated_worktree {\n                self.ensure_coordination_process_lock()\n                    .map_err(anyhow::Error::msg)?;\n            }\n            if self.coordination_process_lock_required && self.state_path.is_none() {\n                return Err(anyhow!(\n                    \"write-capable sub-agent launch requires a durable coordination state path\"\n                ));\n            }\n        }\n        let durable_launch_snapshot =\n            write_capable.then(|| (self.worker_records.clone(), self.coordination.clone()));\n        let persisted_claim = if write_capable {\n            options\n                .write_claim\n                .clone()\n                .map(|mut claim| {\n                    claim.owner = agent_id.clone();\n                    let claim = if options.claim_pre_namespaced {\n                        claim\n                    } else {\n                        self.namespace_write_claim(\n                            &agent.workspace,\n                            options.isolated_worktree,","sourceCodeStart":6335,"sourceCodeEnd":6371,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tools/subagent/mod.rs#L6335-L6371","documentation":"Launching a write-capable sub-agent (profile permissions.write == true) requires durable coordination state: if the manager's coordination process lock is required (shared-workspace contention control) but no durable state_path is configured, the spawn is refused before launch. The guarantee being protected: write contention receipts and worker registration must survive a crash, which is impossible without a durable path.","triggerScenarios":"A write-capable spawn (non-isolated-worktree) on a manager constructed without a state_path while coordination_process_lock_required is set (require_coordination_process_lock wired by the host); embedding or test setups building an in-memory manager (state_path: None default) but enabling the shared-workspace lock; deployments where the state directory configuration was dropped.","commonSituations":"Custom embeddings of the Codewhale TUI manager without the app's state directory; test harnesses constructing managers with defaults that then exercise write-permission profiles; config regressions removing the state root while [subagents] write permissions remain enabled.","solutions":["Configure a durable coordination state path for the manager (the app wires state_path from its persistent state directory; embeddings must pass one at construction instead of the in-memory default)","Spawn write-capable children with isolated_worktree set — isolated worktree children mutate their own checkout and skip the shared-workspace lock requirement","Keep the sub-agent read-only (permissions.write = false) if durable coordination is genuinely unavailable"],"exampleFix":"// before (in-memory manager, write-capable spawn fails)\nlet manager = SubAgentManager::new(/* ... */); // state_path: None\nmanager.spawn_subagent_from_input(&write_request).await?; // refuses\n\n// after\nlet manager = SubAgentManager::new(/* ... */)\n    .with_state_path(state_dir.join(\"subagents/state.json\"));\nmanager.spawn_subagent_from_input(&write_request).await?;","handlingStrategy":"validation","validationCode":"// Before spawning writers on a shared workspace, ensure durable state exists.\nanyhow::ensure!(\n    state_path.join(\"subagents/state.json\").exists(),\n    \"write-capable children need a durable coordination state path; \\\n     configure the state directory or use isolated worktrees\"\n);","typeGuard":null,"tryCatchPattern":"Catch 'requires a durable coordination state path' as a configuration error: stop the spawn path, surface a setup instruction, and re-run after the state path is configured — retrying without config change always fails.","preventionTips":["Wire a persistent state directory into the manager at construction whenever write-permission profiles are enabled","Smoke-test one write-capable spawn at startup to fail fast on missing configuration","Default orchestration templates to isolated-worktree children for any task that writes"],"tags":["subagent","rust","coordination","state-persistence","write-permissions","configuration"],"backgroundTag":"missing-required-config","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}