Hmbown/CodeWhale · error
Automation admission execution ownership is unverified or…
Error message
Automation admission execution ownership is unverified or belongs to another Runtime
What it means
After confirming the dispatch belongs to the current task store, the library checks that the dispatch's execution_scope equals the task manager's execution scope. A mismatch means the admission's execution ownership is either unverified or belongs to a different Runtime instance, so the bound task cannot safely be dispatched here. This is the per-dispatch ownership check complementing the store-path check.
Solutions
- Ensure the Runtime that replays the dispatch is configured with the same execution_scope that admitted it
- Re-admit the automation in the current Runtime so a matching scope is recorded
- Fix the Runtime's execution-scope configuration if it was changed after the admission was created
- Reject/discard foreign dispatch records rather than forcing dispatch
Example fix
// before // runtime scope changed after admission dispatch_bound_task(&mut dispatch, &task_id, &tasks).await?; // after assert_eq!(dispatch.execution_scope.as_deref(), Some(tasks.execution_scope())); dispatch_bound_task(&mut dispatch, &task_id, &tasks).await?;
Defensive patterns
Strategy: validation
Validate before calling
if dispatch.execution_scope.as_deref() != Some(tasks.execution_scope()) {
return Err(anyhow!("dispatch scope mismatch; cannot dispatch here"));
} Type guard
fn owned_by_current(d: &AutomationDispatch, tasks: &SharedTaskManager) -> bool {
d.execution_scope.as_deref() == Some(tasks.execution_scope())
} Prevention
- Pin the Runtime's execution scope in config and never change it after admissions exist
- Only replay admissions produced by the same Runtime scope
- Detect scope drift at startup (compare stored scopes to configured scope) and fail fast
- When running multiple Runtimes, partition the data directory per scope
When it happens
Trigger: Calling dispatch_bound_task where dispatch.execution_scope.as_deref() != Some(tasks.execution_scope()) — the scope is None (never verified) or names another Runtime's scope.
Common situations: Two Runtime processes sharing a data directory but with different execution scopes; a dispatch record copied from another environment; a legacy record with execution_scope stripped or unset; misconfigured scope in the Runtime that produced the admission.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Automation belongs to another Runtime execution scope
- Automation execution ownership is unverified
- Automation admission belongs to a different task store; it…
- Automation name is required
- Automation run has no durable task binding
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/5cde7e36d231a36c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/automation_manager.rs:2103
});
Ok(())
}
fn check_dispatch_store(dispatch: &AutomationDispatch, tasks: &SharedTaskManager) -> Result<()> {
if tasks.data_dir().canonicalize()? != dispatch.task_data_dir.canonicalize()? {
bail!("Automation admission belongs to a different task store; it cannot be replayed here");
}
Ok(())
}
async fn dispatch_bound_task(
dispatch: &mut AutomationDispatch,
task_id: &str,
tasks: &SharedTaskManager,
) -> Result<crate::task_manager::TaskRecord> {
check_dispatch_store(dispatch, tasks)?;
if dispatch.execution_scope.as_deref() != Some(tasks.execution_scope()) {
bail!(
"Automation admission execution ownership is unverified or belongs to another Runtime"
);
}
let task = if dispatch.accepted {
tasks
.read_bound_task(task_id)?
.context("Accepted automation task is missing; refusing to replay it")?
} else {
tasks
.recover_task_admission(dispatch.request.clone(), task_id.to_owned())
.await?
};
crate::task_manager::validate_bound_task_request(&task, &dispatch.request)?;
dispatch.accepted = true;
dispatch.suppress_report = dispatch.delivery_mode == AutomationDeliveryMode::Watcher
&& task.status == TaskStatus::Completed
&& task
.result_summaryView on GitHub (pinned to 433685b202)