{"record":{"id":"2cccba615cc61490","repo":"Hmbown/CodeWhale","slug":"user-input-request-input-id-has-an-indetermina","errorCode":null,"errorMessage":"User-input request '{input_id}' has an indeterminate terminal receipt; inspect Runtime storage before retrying","messagePattern":"User-input request '(.+?)' has an indeterminate terminal receipt; inspect Runtime storage before retrying","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":3284,"sourceCode":"        &self,\n        thread_id: &str,\n        input_id: &str,\n        response: crate::tools::user_input::UserInputResponse,\n    ) -> Result<bool> {\n        let engine = {\n            let active = self.active.lock().await;\n            let Some(state) = active.engines.get(thread_id) else {\n                bail!(\"thread '{thread_id}' not found\");\n            };\n            state.engine.clone()\n        };\n        let request = match self.claim_pending_user_input(thread_id, input_id) {\n            PendingUserInputClaim::Claimed(request) => request,\n            PendingUserInputClaim::Missing | PendingUserInputClaim::Settling => {\n                return Ok(false);\n            }\n            PendingUserInputClaim::Indeterminate => {\n                bail!(\n                    \"User-input request '{input_id}' has an indeterminate terminal receipt; inspect Runtime storage before retrying\"\n                );\n            }\n        };\n\n        // This child task deliberately outlives the HTTP future. Once a\n        // request is claimed, client disconnect/cancellation cannot strand it\n        // between durable acceptance and engine delivery.\n        let manager = self.clone();\n        let thread_id = thread_id.to_string();\n        tokio::spawn(async move {\n            manager\n                .settle_claimed_user_input(\n                    &thread_id,\n                    Some(engine),\n                    request,\n                    UserInputTerminalOutcome::Answered(response),\n                )","sourceCodeStart":3266,"sourceCodeEnd":3302,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/runtime_threads.rs#L3266-L3302","documentation":"submit_user_input claimed input_id and got PendingUserInputClaim::Indeterminate: a previous answer attempt for this request hit a failed append whose rollback also failed, leaving entry.indeterminate = true. The runtime refuses to accept or re-deliver an answer whose durable receipt cannot be established, because either action could duplicate or disclose a response.","triggerScenarios":"Retrying submit_user_input with the same input_id after the first attempt's spawned delivery task failed non-retry-safely (mark_pending_user_input_indeterminate ran). Guard at runtime_threads.rs:3284-3287, flag logic at :2993-3013.","commonSituations":"Storage I/O failure during the first submit; automatic client retry after an HTTP timeout where the server may have already committed; process kill mid-append.","solutions":["Do not retry the same input_id - the tombstone is intentional","Inspect the runtime store's JSONL log for the user_input answer receipt to learn whether the first attempt committed","Fix the underlying storage problem, then restart/reconcile the runtime so pending state is rebuilt from disk","Design the client to treat 'unknown outcome' as an operator-visible incident, not a retryable error"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// The indeterminate bail is terminal for this input_id - escalate.\nmatch manager.submit_user_input(thread_id, input_id, response).await {\n    Ok(accepted) => Ok(accepted),\n    Err(e) if e.to_string().contains(\"indeterminate terminal receipt\") => {\n        tracing::error!(%input_id, \"answer receipt unknown; inspect Runtime storage\");\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Treat submit timeouts on flaky links as 'outcome unknown' - do not blind-retry the same input_id","Keep storage reliable so answer appends and their rollbacks succeed","Persist the input_id so an incident can be reconciled against the JSONL log later"],"tags":["user-input","data-integrity","fail-closed","idempotency","runtime"],"backgroundTag":"indeterminate-write-state","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}