{"record":{"id":"6ad92f0ae1b3a2dd","repo":"Hmbown/CodeWhale","slug":"continual-harness-is-full-max-entries-entries","errorCode":null,"errorMessage":"continual harness is full ({MAX_ENTRIES} entries); remove an obsolete entry before refining again","messagePattern":"continual harness is full \\((.+?) entries\\); remove an obsolete entry before refining again","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/continual_harness.rs","lineNumber":111,"sourceCode":"pub fn refine(workspace: &Path, refinement: HarnessRefinement) -> Result<HarnessEntry> {\n    let refinement = validate_refinement(refinement)?;\n    let path = state_path_for_write(workspace)?;\n    with_write_lock(&path, || {\n        // Reload *inside* the cross-process writer lock. Atomic publication\n        // protects readers from torn JSON, while this transaction prevents\n        // two approved refinements from both deriving changes from a stale\n        // snapshot and dropping one another's entry.\n        let mut state = load_state(&path)?;\n\n        if let Some(existing) = state.entries.iter().find(|entry| {\n            entry.kind == refinement.kind\n                && entry.title == refinement.title\n                && entry.content == refinement.content\n        }) {\n            return Ok(existing.clone());\n        }\n        if state.entries.len() >= MAX_ENTRIES {\n            bail!(\n                \"continual harness is full ({MAX_ENTRIES} entries); remove an obsolete entry before refining again\"\n            );\n        }\n\n        let entry = HarnessEntry {\n            id: format!(\"h_{}\", Uuid::new_v4().simple()),\n            kind: refinement.kind,\n            title: refinement.title,\n            content: refinement.content,\n            evidence: refinement.evidence,\n        };\n        state.schema_version = SCHEMA_VERSION;\n        state.entries.push(entry.clone());\n        save_state(&path, &state)?;\n        // Journalled after the state is durable: a logged edit that never\n        // landed would be worse than an unlogged one.\n        append_journal(&path, \"refine\", &entry)?;\n        Ok(entry)","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/continual_harness.rs#L93-L129","documentation":"Thrown by continual_harness::refine when the workspace harness state already holds MAX_ENTRIES (24) entries and the new refinement is not an exact duplicate. The ledger is intentionally bounded; an identical (kind, title, content) refinement dedupes and returns the existing entry even at capacity, so only genuinely new entries are refused.","triggerScenarios":"Calling the harness refine tool (crate::continual_harness::refine) on a workspace whose state file already has 24 entries. The check runs inside the cross-process write lock after reloading state, so concurrent refines cannot slip past it.","commonSituations":"A long-lived project accumulating prompt notes, sub-agent specs, and skill hints; the model attempting another refinement after the ledger filled up.","solutions":["Remove an obsolete entry first: call continual_harness::remove(workspace, id) with the entry's id","List entries via overview(workspace) to find the least valuable id to drop","Consolidate overlapping refinements into one entry instead of adding more"],"exampleFix":"// before: refine on a full ledger\nlet entry = continual_harness::refine(&workspace, refinement)?;\n\n// after: make room first\nlet overview = continual_harness::overview(&workspace)?;\nlet obsolete = overview.entries.iter().min_by_key(|e| (e.kind.as_str().len(), e.title.clone()));\nif let Some(obsolete) = obsolete {\n    continual_harness::remove(&workspace, &obsolete.id)?;\n}\nlet entry = continual_harness::refine(&workspace, refinement)?;","handlingStrategy":"validation","validationCode":"// Check capacity and dedupe before refining:\nlet overview = continual_harness::overview(&workspace)?;\nlet duplicate = overview.entries.iter().any(|e|\n    e.kind == refinement.kind && e.title == refinement.title && e.content == refinement.content\n);\nif !duplicate && overview.entries.len() >= 24 {\n    // prompt the caller to remove an obsolete entry by id first\n    let removable = pick_obsolete_entry(&overview.entries);\n    continual_harness::remove(&workspace, &removable.id)?;\n}\nlet entry = continual_harness::refine(&workspace, refinement)?;","typeGuard":null,"tryCatchPattern":"match continual_harness::refine(&workspace, refinement) {\n    Ok(entry) => { /* ... */ }\n    Err(error) if error.to_string().contains(\"continual harness is full\") => {\n        // list entries, let the user pick one to remove, then retry once\n    }\n    Err(error) => return Err(error),\n}","preventionTips":["Track entry count in the UI and warn as it approaches 24","Prefer updating an existing entry over adding near-duplicates; exact duplicates dedupe automatically","Periodically prune skill hints and prompt notes that no longer match the project"],"tags":["rust","tui","harness","capacity","state"],"backgroundTag":"capacity-limit-exceeded","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}