Hmbown/CodeWhale · error · anyhow::Error

continual harness entry id cannot be empty

Error message

continual harness entry id cannot be empty

What it means

Thrown by continual_harness::remove when the entry id, after trimming, is empty. Ids are opaque strings like "h_<uuid-simple>"; the guard rejects blank input before taking the write lock so a caller cannot issue a meaningless delete.

Source

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

            content: refinement.content,
            evidence: refinement.evidence,
        };
        state.schema_version = SCHEMA_VERSION;
        state.entries.push(entry.clone());
        save_state(&path, &state)?;
        // Journalled after the state is durable: a logged edit that never
        // landed would be worse than an unlogged one.
        append_journal(&path, "refine", &entry)?;
        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)
    })
}

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Pass the exact id from overview(workspace).entries (format h_<32-hex>)
  2. Check the id is non-empty after trimming before calling remove
  3. If the id came from user selection, validate a row is actually selected

Example fix

// before
continual_harness::remove(&workspace, "")?;

// after
let id = selected_entry.id.clone();
continual_harness::remove(&workspace, &id)?;
Defensive patterns

Strategy: validation

Validate before calling

let id = id.trim();
if id.is_empty() {
    return Err(anyhow::anyhow!("select an entry to remove first"));
}
let removed = continual_harness::remove(&workspace, id)?;

Type guard

fn is_valid_entry_id(id: &str) -> bool {
    let id = id.trim();
    !id.is_empty() && id.starts_with("h_") && id.len() == 2 + 32
}

Prevention

When it happens

Trigger: Calling remove(workspace, "") or remove(workspace, " ") — e.g. a UI passing an unselected row's id, or a script forwarding an unset variable.

Common situations: A tool caller forwarding an empty selection; string building that drops the id; copy-paste from a truncated example.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/e58786a8e0f73b63. Report an issue: GitHub.