{"record":{"id":"1cf56fc434418241","repo":"Hmbown/CodeWhale","slug":"task-execution-scope-is-unverified-or-belongs-to-another","errorCode":null,"errorMessage":"Task execution scope is unverified or belongs to another Runtime; refusing adoption","messagePattern":"Task execution scope is unverified or belongs to another Runtime; refusing adoption","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/task_manager.rs","lineNumber":1774,"sourceCode":"                kind: \"queued\".to_string(),\n                summary: \"Task queued\".to_string(),\n                detail_path: None,\n            }],\n        };\n\n        self.admit_task_record(task, false).await\n    }\n\n    async fn admit_task_record(&self, task: TaskRecord, recover_stage: bool) -> Result<TaskRecord> {\n        {\n            let mut state = self.state.lock().await;\n            let _transaction = self.lock_store().await?;\n            self.refresh_locked(&mut state)?;\n            if self.cancel_token.is_cancelled() {\n                bail!(\"Task manager is shutting down; admission is closed\");\n            }\n            if task.execution_scope.as_deref() != Some(self.execution_scope()) {\n                bail!(\n                    \"Task execution scope is unverified or belongs to another Runtime; refusing adoption\"\n                );\n            }\n            let task_path = self.tasks_dir.join(format!(\"{}.json\", task.id));\n            // The staged extension is intentionally not `.json`, so startup\n            // replay ignores an interrupted create until the queue write has\n            // succeeded and this file is atomically promoted.\n            let staged_task_path = self.tasks_dir.join(format!(\".{}.json.pending\", task.id));\n            if recover_stage {\n                if let Some(accepted) = self.read_bound_task(&task.id)? {\n                    validate_bound_task_request(&accepted, &NewTaskRequest::from_task(&task))?;\n                    return Ok(accepted);\n                }\n                let current = read_bound_task_file(&staged_task_path, &task.id)?\n                    .context(\"Unaccepted task stage disappeared during recovery\")?;\n                if serde_json::to_value(&current)? != serde_json::to_value(&task)? {\n                    bail!(\"Unaccepted task stage changed during recovery\");\n                }","sourceCodeStart":1756,"sourceCodeEnd":1792,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/task_manager.rs#L1756-L1792","documentation":"During admission, a task record's execution_scope must exactly match the current Runtime's execution_scope(). A record whose scope is missing (unverified) or belongs to another Runtime is refused for adoption, preventing a worker from executing tasks created under a different execution identity (different lease namespace/generation).","triggerScenarios":"Calling admit_task_record (via recovery, adoption, or add paths) with a TaskRecord whose execution_scope is None or whose stored scope string differs from self.execution_scope() — e.g. a task file copied from another profile/machine or created before a scope regeneration.","commonSituations":"Copying a tasks directory between machines or profiles; runtime scope regenerating after an id-format change (related to validate_execution_id); loading old durable records from a previous version that stored no scope.","solutions":["Only adopt task records produced by the same Runtime/scope; verify task.execution_scope equals the current execution_scope() before admission","Delete or archive durable task files from foreign scopes so recovery does not attempt to adopt them","If scopes legitimately changed across an upgrade, run the migration that re-stamps records with the new scope","Set execution_scope explicitly when constructing TaskRecord; never admit records with a None scope"],"exampleFix":"// before\nmgr.adopt_task(record).await?; // record.execution_scope = Some(\"old-scope\")\n// after\nif record.execution_scope.as_deref() == Some(mgr.execution_scope()) {\n    mgr.adopt_task(record).await?;\n} else {\n    archive_foreign_task(&record)?;\n}","handlingStrategy":"validation","validationCode":"anyhow::ensure!(task.execution_scope.as_deref() == Some(mgr.execution_scope()), \"task belongs to another runtime scope\");","typeGuard":null,"tryCatchPattern":"match adopt_result { Err(e) if e.to_string().contains(\"execution scope\") => archive_foreign_record(&task), r => r?, }","preventionTips":["Never copy task stores between profiles/machines without re-stamping scope","Always populate execution_scope on newly built TaskRecords","Run scope migrations on upgrade before recovery replay"],"tags":["rust","tasks","scope","isolation"],"backgroundTag":"invalid-state-transition","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}