Hmbown/CodeWhale · error
Invalid task execution identity
Error message
Invalid task execution identity
What it means
validate_execution_id enforces that a task execution identifier (scope or generation component) is exactly `length` characters of ASCII hex digits. Any id used to build an execution lease path that is the wrong length or contains non-hex characters is rejected with this message. This protects lease file paths on disk from malformed or hostile identifiers.
Solutions
- Use the task manager's own generated execution scope/generation values instead of hand-built ones
- Normalize the id: strip non-hex characters and confirm it is exactly 64 hex chars (for scope) before calling
- If migrating from an older id format, regenerate the execution id rather than translating the old one
- Log the offending value's length/charset to identify which component (scope vs generation) is malformed
Example fix
// before
let scope = format!("{:x}", runtime_seed); // arbitrary length
// after
use sha2::{Digest, Sha256};
let scope: String = Sha256::digest(runtime_seed).iter().map(|b| format!("{b:02x}")).collect(); // exactly 64 hex chars
validate_execution_id(&scope, 64)?; Defensive patterns
Strategy: validation
Validate before calling
fn valid_exec_id(s: &str, len: usize) -> bool { s.len() == len && s.bytes().all(|b| b.is_ascii_hexdigit()) } Try / catch
match result { Err(e) if e.to_string().contains("Invalid task execution identity") => { /* regenerate execution id and retry once */ } , r => r?, } Prevention
- Always take execution ids from the manager's own generators
- Store ids as lowercase hex strings, never base64 or uuid-with-dashes
- Add a unit check on ids deserialized from durable state before use
When it happens
Trigger: Calling execution_lease_path (and thereby lease acquire/renew/release paths) with a scope that is not 64 hex chars, or a generation that is not the expected hex length; passing a truncated, URL-decoded, or differently-formatted execution id into the task manager lease APIs.
Common situations: Constructing execution ids by hand or from external config; upgrading across versions where the id encoding changed (e.g. uuid with dashes vs 64-char hex); a caller storing ids as base64 instead of hex.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- A pinned task provider requires an explicit model
- Invalid durable task id
- Invalid session id
- Task prompt cannot be empty
- agent profile provider cannot be empty
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/687fa222d23e5d27.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/task_manager.rs:1347
scope_owner: Arc<RuntimeProcessOwnerLock>,
) -> Result<Arc<Self>> {
validate_execution_id(&scope, 64)?;
let generation = Uuid::new_v4().simple().to_string();
let path = execution_lease_path(root, &scope, &generation)?;
let owner = RuntimeProcessOwnerLock::try_acquire_file(&path, true)?
.context("Task execution generation is already owned")?;
Ok(Arc::new(Self {
scope,
generation,
_scope_owner: scope_owner,
_generation_owner: owner,
}))
}
}
fn validate_execution_id(value: &str, length: usize) -> Result<()> {
if value.len() != length || !value.bytes().all(|byte| byte.is_ascii_hexdigit()) {
bail!("Invalid task execution identity");
}
Ok(())
}
fn execution_lease_path(root: &Path, scope: &str, generation: &str) -> Result<PathBuf> {
validate_execution_id(scope, 64)?;
validate_execution_id(generation, 32)?;
Ok(root
.join("execution-owners")
.join(format!("{scope}.{generation}.lock")))
}
#[cfg(test)]
pub(crate) fn test_execution_scope(name: &str) -> String {
use sha2::{Digest, Sha256};
Sha256::digest(name.as_bytes())
.iter()
.map(|byte| format!("{byte:02x}"))View on GitHub (pinned to 73e0f67d83)