{"record":{"id":"a075ccd1e6ac0a9f","repo":"tinyhumansai/openhuman","slug":"tinyagents-harness-run-failed-e","errorCode":null,"errorMessage":"tinyagents harness run failed: {e}","messagePattern":"tinyagents harness run failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/tinyagents/mod.rs","lineNumber":981,"sourceCode":"            // Otherwise prefer the original typed provider error (preserves\n            // `AgentError` downcasts the caller relies on) over the harness's\n            // string wrap — this is where a genuine model/provider failure that\n            // halted the run is re-surfaced with its real classification.\n            // #4469 item 3: `into_inner` recovers a poisoned slot so a panic in\n            // one run can't cascade into a second panic here that would mask the\n            // original typed provider error.\n            if let Some(original) = error_slot\n                .lock()\n                .unwrap_or_else(std::sync::PoisonError::into_inner)\n                .take()\n            {\n                tracing::debug!(\n                    model,\n                    \"[tinyagents] re-surfacing typed provider error from error_slot as the run failure — #4457 defect B\"\n                );\n                return Err(original);\n            }\n            return Err(anyhow::anyhow!(\"tinyagents harness run failed: {e}\"));\n        }\n    };\n    // Durable journal: the harness returned a transcript, so stamp the terminal\n    // completed status (best-effort, non-fatal). The event stream carries no\n    // run-terminal event, so this caller-driven write is authoritative.\n    if let Some(journal) = &turn_journal {\n        journal.finish_completed().await;\n    }\n    // Context-compression provenance (issue #4249, 03.1 item 6): the harness's\n    // `AgentEvent::Compressed` projection only carries token deltas, so drain the\n    // compression middleware's `records()` here — each carries the full\n    // `CompressionProvenance` (source ids + before/after token estimates + policy\n    // reason) built by `ModelSummarizer`. Surfaced at info with a\n    // grep-friendly `[context]` prefix so every compaction is auditable, not just\n    // its net token saving.\n    if let Some(mw) = &compression_mw {\n        let records = mw.records();\n        if !records.is_empty() {","sourceCodeStart":963,"sourceCodeEnd":999,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/tinyagents/mod.rs#L963-L999","documentation":"Terminal wrapper when the tinyagents harness drive future returns Err and the shared error_slot is empty (mod.rs:981). Provider-shaped failures are intercepted just above and re-surfaced as the original typed provider error (#4457 defect B), so this message covers non-provider failures: middleware errors, graph errors, internal harness faults. The {e} chain is the actual cause.","triggerScenarios":"A middleware in the assembled turn harness returning Err (context compression, journalling, event bridge); TinyAgentsError::Graph step failures inside the harness run; a newly added middleware that errors on specific event shapes; panics caught and converted to errors by the harness.","commonSituations":"Right after adding or upgrading harness middleware; failures that only reproduce mid-turn (after model calls started); sparse logs because the typed-error slot path never triggered.","solutions":["Enable debug/trace logging and grep for [tinyagents] — the re-surfacing branch and middlewares emit diagnostics before this line","Inspect the turn journal / AgentEvent stream for the last event before the failure to identify the failing stage","Re-run with the same inputs to separate transient (provider/network — usually surfaced via error_slot instead) from deterministic (middleware bug) causes","If deterministic, capture {e:#} (full chain) plus the run_id and file an issue"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Keep the full cause chain and persist a terminal status so replay sees it\nlet outcome = run_turn_harness(assembled).await;\nif let Err(e) = outcome {\n    tracing::error!(\"[turn] harness run failed: {e:#}\");\n    journal.finish_failed(&e.to_string()).await;\n    return Err(e);\n}","preventionTips":["Run with [tinyagents] debug/trace enabled during harness middleware development","Prefer typed provider errors via the error_slot pattern so provider failures keep their classification","Journal turn events so the last event before a failure identifies the stage"],"tags":["rust","llm","harness","runtime","middleware"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}