Hmbown/CodeWhale · error
Bound task identity or schema does not match its durable…
Error message
Bound task identity or schema does not match its durable admission
What it means
When reading a durable bound-task file, the decoded TaskRecord must have the same id as the file's bound task id and a schema_version not newer than the current supported version. Otherwise the durable admission cannot be matched to the request, so the read fails rather than trusting a mismatched record.
Solutions
- Upgrade to the newer app version whose CURRENT_TASK_SCHEMA_VERSION covers the file
- Correct the task_id argument to match the record actually stored in the file
- Fix or remove the mis-named task file so identity matches its durable location
Example fix
// before: reading with mismatched id
let t = manager.read_bound_task("task_0000000000000000")?;
// after: match id to file content
let t = manager.read_bound_task(&stored_task_id)?; // stored_task_id == record.id Defensive patterns
Strategy: validation
Validate before calling
let record: TaskRecord = serde_json::from_slice(&bytes)?;
if record.id != requested_id { return Err(anyhow!("id mismatch with durable file")); }
if record.schema_version > CURRENT_TASK_SCHEMA_VERSION { return Err(anyhow!("schema too new")); } Type guard
fn bound_record_matches(bytes: &[u8], task_id: &str, supported: u32) -> Option<TaskRecord> {
let t: TaskRecord = serde_json::from_slice(bytes).ok()?;
(t.id == task_id && t.schema_version <= supported).then_some(t)
} Try / catch
match manager.read_bound_task(id).await {
Err(e) if e.to_string().contains("identity or schema does not match") => {
// try newer app version, or locate the correctly named file
eprintln!("bound record unusable for {id}: {e}");
}
other => other?,
} Prevention
- Never rename task files without updating the inner id
- Keep app versions across a shared store within the same schema version
- Check schema_version support before reading a store written elsewhere
When it happens
Trigger: Calling read_bound_task_file (directly or via recovery/admission) when the JSON record's `id` differs from the requested task_id, or its schema_version exceeds CURRENT_TASK_SCHEMA_VERSION.
Common situations: A task file was renamed or copied under the wrong id; a newer app version wrote the file and an older version reads it (forward-compatibility gap); a client passed a task_id that doesn't match the stored record.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Automation transaction cannot replace its identity
- budget schema_version changed
- Duplicate policy identity.
- Duplicate producer incarnation/sequence in evidence bundle…
- Invalid preallocated task id: expected task_<16hex>
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/f63a67d900b57fa8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/task_manager.rs:3097
fn validate_preallocated_task_id(task_id: &str) -> Result<()> {
if task_id.len() != 21
|| !task_id.starts_with("task_")
|| !task_id[5..].chars().all(|ch| ch.is_ascii_hexdigit())
{
bail!("Invalid preallocated task id: expected task_<16hex>");
}
Ok(())
}
fn read_bound_task_file(path: &Path, task_id: &str) -> Result<Option<TaskRecord>> {
let bytes = match fs::read(path) {
Ok(bytes) => bytes,
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(None),
Err(error) => return Err(error).context("read bound task"),
};
let task: TaskRecord = serde_json::from_slice(&bytes).context("decode bound task")?;
if task.id != task_id || task.schema_version > CURRENT_TASK_SCHEMA_VERSION {
bail!("Bound task identity or schema does not match its durable admission");
}
Ok(Some(task))
}
pub(crate) fn validate_bound_task_request(
task: &TaskRecord,
request: &NewTaskRequest,
) -> Result<()> {
if task.prompt != request.prompt.trim()
|| task.owner_session_id != request.owner_session_id
|| task.model_provider != request.model_provider
|| task.model_provider_id != request.model_provider_id
|| request
.model
.as_ref()
.is_some_and(|value| value != &task.model)
|| request
.workspaceView on GitHub (pinned to 73e0f67d83)