nikivdev/code · error

Todo '{}' not found

Error message

Todo '{}' not found

What it means

Raised by find_item_index (src/todo.rs:549), which resolves a user-supplied id against stored todo items by exact match or unique prefix match (item.id == id || item.id.starts_with(id)). It bails when zero items match, meaning the referenced todo does not exist in the todo file.

Source

Thrown at src/todo.rs:549

    if title.starts_with("re-run review:") || title.contains("review timed out") {
        return true;
    }
    item.note
        .as_deref()
        .map(|n| n.to_lowercase().contains("review timed out"))
        .unwrap_or(false)
}

pub(crate) fn find_item_index(items: &[TodoItem], id: &str) -> Result<usize> {
    let mut matches = Vec::new();
    for (idx, item) in items.iter().enumerate() {
        if item.id == id || item.id.starts_with(id) {
            matches.push(idx);
        }
    }

    match matches.len() {
        0 => bail!("Todo '{}' not found", id),
        1 => Ok(matches[0]),
        _ => bail!("Todo id '{}' is ambiguous", id),
    }
}

fn resolve_session_ref(session: Option<&str>, no_session: bool) -> Result<Option<String>> {
    if no_session {
        return Ok(None);
    }

    if let Some(session) = session {
        let trimmed = session.trim();
        return Ok(if trimmed.is_empty() {
            None
        } else {
            Some(trimmed.to_string())
        });
    }

View on GitHub (pinned to a747e741ae)

Solutions

  1. Run the todo list command to see current ids and copy the correct one.
  2. Check you are operating on the same todo file/session the item lives in (pass the right --session flag).
  3. If the item was already removed, no action is needed.
  4. Prefix-match a longer, verified prefix of the id to avoid ambiguity while still matching.

Example fix

// before
todo remove a1b2
// after: list first, then use an id from the listing
f todo list
f todo remove a1b2c3d4e5f6
Defensive patterns

Strategy: validation

Validate before calling

// confirm the id exists before edit/remove/status ops
const listed = execSync("f todo list").toString();
if (!listed.includes(idPrefix)) {
  throw new Error(`id ${idPrefix} not present in current todo list`);
}

Try / catch

try {
  removeTodo(id);
} catch (e) {
  if (String(e).match(/Todo '.*' not found/)) {
    console.error("Refresh ids with `f todo list`; item may already be gone");
  } else throw e;
}

Prevention

When it happens

Trigger: Calling edit, set_status, or remove (via run) with an id that is neither a full item id nor a prefix of any stored item id — e.g. a typo, an id from a different todo file/project, or an id of an already-removed item.

Common situations: Using an id copied from another machine's todo list; the todo was already removed by a parallel invocation; truncated/pasted id with a typo'd character; ids rotating if items are regenerated with new UUIDs.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/de1cf8849ca57e00. Report an issue: GitHub.