Hmbown/CodeWhale · error

Ambiguous task prefix

Error message

Ambiguous task prefix '{}': matches {} tasks

What it means

The same prefix-resolution path throws this when the supplied id_or_prefix is not unique: more than one visible task id starts with that prefix. The library refuses to guess and reports the match count.

Solutions

  1. Provide more characters of the task id so the prefix matches exactly one task.
  2. Use the full task id copied from the task list output.
  3. List tasks filtered to the prefix to see the ambiguous matches and pick the intended one.

Example fix

// before
let id = manager.resolve_task_id_visible_to("a1", actor).await?; // matches a10, a11
// after
let id = manager.resolve_task_id_visible_to("a10", actor).await?;
Defensive patterns

Strategy: validation

Validate before calling

let matching = tasks.iter().filter(|t| t.id.starts_with(prefix)).count();
if matching != 1 { anyhow::bail!("prefix '{prefix}' matches {matching} tasks; use a longer prefix"); }

Prevention

When it happens

Trigger: Calling resolve (get/update/complete by id_or_prefix) with a short prefix like "1" or "a" that matches multiple visible task ids.

Common situations: Users abbreviating task ids too aggressively in agent tool calls; ids sharing a common timestamp or run prefix.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/c3a0257789345e0c. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/task_manager.rs:3318

) -> Result<String> {
    let visible = |record: &TaskRecord| {
        owner_session_id.is_none_or(|owner_session_id| {
            record.owner_session_id.as_deref() == Some(owner_session_id)
        })
    };
    if tasks.get(id_or_prefix).is_some_and(visible) {
        return Ok(id_or_prefix.to_string());
    }
    let matches = tasks
        .iter()
        .filter(|(id, record)| id.starts_with(id_or_prefix) && visible(record))
        .map(|(id, _)| id)
        .cloned()
        .collect::<Vec<_>>();
    match matches.len() {
        0 => bail!("Task not found: {id_or_prefix}"),
        1 => Ok(matches[0].clone()),
        _ => bail!(
            "Ambiguous task prefix '{}': matches {} tasks",
            id_or_prefix,
            matches.len()
        ),
    }
}

fn resolve_task_id_visible_to_operator(
    tasks: &HashMap<String, TaskRecord>,
    id_or_prefix: &str,
    owner_session_id: &str,
    execution_scope: &str,
) -> Result<String> {
    let visible = |record: &TaskRecord| {
        record.owner_session_id.as_deref() == Some(owner_session_id)
            || record.owner_session_id.is_none()
                && !execution_scope.is_empty()
                && record.execution_scope.as_deref() == Some(execution_scope)

View on GitHub (pinned to 73e0f67d83)