{"record":{"id":"9baecfbc0b99890d","repo":"Hmbown/CodeWhale","slug":"deliverable-path-is-outside-the-worker-write-scope-declare","errorCode":null,"errorMessage":"deliverable {path:?} is outside the worker write scope; declare an exact_files entry or a containing write_roots path","messagePattern":"deliverable (.+?) is outside the worker write scope; declare an exact_files entry or a containing write_roots path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":7089,"sourceCode":"        let delivery_paths =\n            delivery::declared_paths(&options.deliverables, options.expected_artifact.as_deref())\n                .map_err(anyhow::Error::msg)?;\n        for path in &delivery_paths {\n            delivery::safe_deliverable_path(&agent.workspace, path).map_err(anyhow::Error::msg)?;\n            let claimed_path = if options.claim_pre_namespaced && !options.isolated_worktree {\n                let prefix = coordination_workspace_prefix(&self.workspace, &agent.workspace)\n                    .map_err(anyhow::Error::msg)?;\n                namespace_coordination_path(&prefix, path).map_err(anyhow::Error::msg)?\n            } else {\n                path.clone()\n            };\n            if !write_capable\n                || !options\n                    .write_claim\n                    .as_ref()\n                    .is_some_and(|claim| claim.contains_path(&claimed_path))\n            {\n                return Err(anyhow!(\n                    \"deliverable {path:?} is outside the worker write scope; declare an exact_files entry or a containing write_roots path\"\n                ));\n            }\n        }\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_registration = write_capable || continuation_from.is_some();","sourceCodeStart":7071,"sourceCodeEnd":7107,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/mod.rs#L7071-L7107","documentation":"Each declared deliverable path must fall inside the worker's write scope. If the agent is write-capable, the spawn validates every deliverable against its write_claim (exact_files or write_roots); a deliverable that is neither covered by an exact_files entry nor contained in a write_roots path is rejected. This prevents workers from being asked to produce files they are not authorized to write.","triggerScenarios":"Spawning a write-capable sub-agent whose `deliverables` list includes a path outside the paths granted by options.write_claim (write_claim.contains_path returns false for it, or write_claim is None).","commonSituations":"Deliverables declared as bare file names or absolute paths while write_roots use relative workspace paths; adding a new deliverable after tightening the write claim; forgetting to declare the deliverable in exact_files at all.","solutions":["Add the deliverable's exact path to the write_claim's exact_files list.","Or add/extend a write_roots entry so it contains (is a parent directory of) the deliverable path.","Verify path forms match: both the deliverable and the claim must resolve against the same workspace root; fix absolute-vs-relative mismatches."],"exampleFix":"// before\nwrite_claim: WriteClaim { write_roots: vec![\"src/\".into()], exact_files: vec![] },\ndeliverables: vec![\"src/report.md\".into(), \"tests/report_test.rs\".into()]\n// after\nwrite_claim: WriteClaim {\n    write_roots: vec![\"src/\".into()],\n    exact_files: vec![\"tests/report_test.rs\".into()],\n},\ndeliverables: vec![\"src/report.md\".into(), \"tests/report_test.rs\".into()]","handlingStrategy":"validation","validationCode":"function deliverablesInScope(deliverables, claim) {\n  return deliverables.every(p =>\n    claim.exactFiles.includes(p) || claim.writeRoots.some(root => p.startsWith(root)));\n}","typeGuard":"const isCovered = (p, claim) =>\n  claim.exact_files.includes(p) || claim.write_roots.some(r => p === r || p.startsWith(r.trim_end_matches('/') + '/'));","tryCatchPattern":"match spawn_result {\n    Err(e) if e.to_string().contains(\"outside the worker write scope\") => fix_write_claim_and_retry(),\n    other => other?,\n}","preventionTips":["Derive the deliverables list from the write claim (or vice versa) in one place, never maintained separately.","Normalize path forms (workspace-relative) for both deliverables and write_roots.","When adding a deliverable, immediately extend exact_files or a write_root."],"tags":["subagent","write-scope","validation"],"backgroundTag":"permission-denied","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}