{"record":{"id":"576684fb878a0342","repo":"Hmbown/CodeWhale","slug":"continual-harness-has-no-entry-id","errorCode":null,"errorMessage":"continual harness has no entry `{id}`","messagePattern":"continual harness has no entry `(.+?)`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/continual_harness.rs","lineNumber":147,"sourceCode":"        Ok(entry)\n    })\n}\n\n/// Remove one exact entry. Returning the removed entry makes deletion\n/// receipts useful without re-reading the state file.\npub fn remove(workspace: &Path, id: &str) -> Result<HarnessEntry> {\n    let id = id.trim();\n    if id.is_empty() {\n        bail!(\"continual harness entry id cannot be empty\");\n    }\n    let path = state_path_for_write(workspace)?;\n    with_write_lock(&path, || {\n        let mut state = load_state(&path)?;\n        let index = state\n            .entries\n            .iter()\n            .position(|entry| entry.id == id)\n            .ok_or_else(|| anyhow!(\"continual harness has no entry `{id}`\"))?;\n        let removed = state.entries.remove(index);\n        state.schema_version = SCHEMA_VERSION;\n        save_state(&path, &state)?;\n        // Removal is the edit most worth recording: the entry is gone from\n        // state, so the journal is the only place its content survives.\n        append_journal(&path, \"remove\", &removed)?;\n        Ok(removed)\n    })\n}\n\n/// Render the bounded, lower-authority state that follows the stable prompt\n/// prefix. Broken or future-version state is intentionally omitted rather\n/// than becoming a prompt-injection path.\n#[must_use]\npub fn prompt_block(workspace: &Path) -> Option<String> {\n    let overview = overview(workspace).ok()?;\n    if overview.entries.is_empty() {\n        return None;","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/continual_harness.rs#L129-L165","documentation":"Thrown by `continual_harness::remove` (crates/tui/src/continual_harness.rs:147). The function trims the id, loads the workspace harness state under a cross-process write lock, and searches `entries` for an exact id match. When no entry carries that id it bails before any mutation, so the state file and journal are untouched. Entry ids are `h_<uuid>` strings minted by `refine`.","triggerScenarios":"Calling `remove(workspace, id)` twice with the same id (the first call already deleted it); passing an id taken from an older `overview()` snapshot that another session or process has since removed; a typo'd or differently-cased id.","commonSituations":"A harness tool/UI retries removal after a timeout; two Codewhale sessions share one workspace state file; a cleanup script replays recorded ids against state that has changed.","solutions":["Call `continual_harness::overview(workspace)` and pass an id that exists in `entries` right now","If removal should be idempotent, treat this specific error as success by matching the 'continual harness has no entry' message before propagating","Check the harness journal to confirm the entry was not already removed under the same id"],"exampleFix":"// before\nlet removed = continual_harness::remove(&workspace, &id)?;\n\n// after\nmatch continual_harness::remove(&workspace, &id) {\n    Ok(entry) => { /* use removal receipt */ }\n    Err(err) if err.to_string().contains(\"continual harness has no entry\") => {\n        // already removed; treat as success\n    }\n    Err(err) => return Err(err),\n}","handlingStrategy":"validation","validationCode":"let overview = continual_harness::overview(&workspace)?;\nlet id = id.trim();\nif !overview.entries.iter().any(|entry| entry.id == id) {\n    anyhow::bail!(\"refusing to remove unknown harness id {id}\");\n}\ncontinual_harness::remove(&workspace, id)?;","typeGuard":"fn harness_entry_exists(\n    overview: &continual_harness::HarnessOverview,\n    id: &str,\n) -> bool {\n    overview.entries.iter().any(|entry| entry.id == id.trim())\n}","tryCatchPattern":"match continual_harness::remove(&workspace, &id) {\n    Ok(entry) => { /* removal receipt */ }\n    Err(err) if err.to_string().contains(\"continual harness has no entry\") => {\n        // idempotent no-op: entry already gone\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Re-run overview() immediately before remove(); ids go stale when sessions share a workspace","Trim ids before use and expect the `h_<uuid>` shape","Design removal flows to be idempotent so a double-remove is harmless"],"tags":["rust","state","idempotency","continual-harness"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}