Hmbown/CodeWhale · error · anyhow::Error

continual harness has no entry

Error message

continual harness has no entry `{id}`

What it means

The continual harness journal's remove operation scans the persisted state for an entry with the given id; if none exists it fails with this error. Nothing is removed or journaled when the id is unknown.

Solutions

  1. List current entries first and use an id that exists, then call remove.
  2. Handle Err gracefully for idempotent removal — treat this error as 'already gone' and continue.
  3. Verify the harness is pointed at the same state file that contains the entry (same working directory or explicit path).

Example fix

// before
harness.remove(&id)?; // fails if already removed
// after
if harness.list()?.iter().any(|e| e.id == id) {
    harness.remove(&id)?;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if !harness.list()?.iter().any(|e| e.id == id) {
    return Ok(()); // already removed
}

Try / catch

match harness.remove(&id) {
    Err(e) if e.to_string().contains(&format!("no entry `{id}`")) => { /* idempotent no-op */ }
    other => other?,
}

Prevention

When it happens

Trigger: Calling ContinualHarness::remove (public) with an id string not present in the harness state file, or one already removed in a previous call.

Common situations: A stale id from an earlier session or a different harness state path (working directory changed so the state file location differs); double-removal after a previous successful delete; typo or truncated id.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at crates/tui/src/continual_harness.rs:147

        Ok(entry)
    })
}

/// Remove one exact entry. Returning the removed entry makes deletion
/// receipts useful without re-reading the state file.
pub fn remove(workspace: &Path, id: &str) -> Result<HarnessEntry> {
    let id = id.trim();
    if id.is_empty() {
        bail!("continual harness entry id cannot be empty");
    }
    let path = state_path_for_write(workspace)?;
    with_write_lock(&path, || {
        let mut state = load_state(&path)?;
        let index = state
            .entries
            .iter()
            .position(|entry| entry.id == id)
            .ok_or_else(|| anyhow!("continual harness has no entry `{id}`"))?;
        let removed = state.entries.remove(index);
        state.schema_version = SCHEMA_VERSION;
        save_state(&path, &state)?;
        // Removal is the edit most worth recording: the entry is gone from
        // state, so the journal is the only place its content survives.
        append_journal(&path, "remove", &removed)?;
        Ok(removed)
    })
}

/// Render the bounded, lower-authority state that follows the stable prompt
/// prefix. Broken or future-version state is intentionally omitted rather
/// than becoming a prompt-injection path.
#[must_use]
pub fn prompt_block(workspace: &Path) -> Option<String> {
    let overview = overview(workspace).ok()?;
    if overview.entries.is_empty() {
        return None;

View on GitHub (pinned to 73e0f67d83)