Hmbown/CodeWhale · error

Automation admission belongs to a different task store; it…

Error message

Automation admission belongs to a different task store; it cannot be replayed here

What it means

Before replaying an admitted automation dispatch, the library verifies that the dispatch's recorded task_data_dir matches the current SharedTaskManager's data directory (compared via canonicalize). If they differ, the admission was created against a different task store and cannot be replayed here; executing it would bind the task into the wrong store. The error makes store mismatch an explicit failure instead of silently running an automation in the wrong context.

Solutions

  1. Replay the dispatch against the task manager whose data_dir matches dispatch.task_data_dir
  2. Re-admit the automation in the current store (create a fresh dispatch) instead of replaying the foreign one
  3. Point the task manager at the original data directory (restore the expected path) if the record is the one you want
  4. If migrating stores deliberately, rewrite dispatch.task_data_dir to the new canonical path via a migration, not at dispatch time

Example fix

// before
dispatch_bound_task(&mut dispatch, &task_id, &wrong_store_tasks).await?;
// after
if tasks.data_dir().canonicalize()? == dispatch.task_data_dir.canonicalize()? {
    dispatch_bound_task(&mut dispatch, &task_id, &tasks).await?;
} else {
    // re-admit in this store or route to the owning store
}
Defensive patterns

Strategy: validation

Validate before calling

if tasks.data_dir().canonicalize()? != dispatch.task_data_dir.canonicalize()? {
    return Err(anyhow!("dispatch belongs to a different task store"));
}

Try / catch

match dispatch_bound_task(&mut dispatch, &task_id, &tasks).await {
    Err(e) if e.to_string().contains("different task store") => {
        // route to owning store or re-admit locally
    },
    other => other?,
}

Prevention

When it happens

Trigger: Calling dispatch_bound_task (which calls check_dispatch_store) with a dispatch whose task_data_dir canonicalizes to a different path than tasks.data_dir() — e.g. dispatching a trigger or run record persisted under another profile/data root.

Common situations: Copying automation state files between machines or between dev and production data directories; changing CODEX_HOME/data dir between runs; running two profiles concurrently and replaying a record from the other profile; restoring backups into a different location.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/ff937b405662da15. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/automation_manager.rs:2091

        execution_scope: automation.execution_scope.clone(),
        request: automation_task_request(automation),
        task_data_dir: task_data_dir
            .canonicalize()
            .context("resolve task store before automation admission")?,
        accepted: false,
        delivery_mode: automation.delivery_mode(),
        suppress_report: false,
        schedule: scheduled.then(|| AdmittedSchedule {
            updated_at: automation.updated_at,
            rrule: automation.rrule.clone(),
        }),
    });
    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)?

View on GitHub (pinned to 433685b202)