{"record":{"id":"01e10ed12ca92707","repo":"Hmbown/CodeWhale","slug":"sub-agent-task-must-not-park-waiting-for-checkpoint-input","errorCode":null,"errorMessage":"sub-agent task must not park waiting for checkpoint input","messagePattern":"sub-agent task must not park waiting for checkpoint input","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/tests.rs","lineNumber":9015,"sourceCode":"                {\n                    return (id, reason);\n                }\n            }\n            tokio::time::sleep(Duration::from_millis(10)).await;\n        }\n    })\n    .await\n    .expect(\"API timeout should publish an Interrupted mailbox lifecycle event\");\n    assert_eq!(interrupted_envelope.0, agent_id);\n    assert!(\n        interrupted_envelope.1.contains(\"API call timed out\"),\n        \"reason should carry the timeout context: {}\",\n        interrupted_envelope.1\n    );\n\n    tokio::time::timeout(Duration::from_secs(5), task_handle)\n        .await\n        .expect(\"sub-agent task must not park waiting for checkpoint input\")\n        .expect(\"sub-agent task should finish\");\n    assert_eq!(\n        calls.load(Ordering::SeqCst),\n        SUBAGENT_API_TIMEOUT_MAX_RETRIES.saturating_add(1) as usize,\n        \"needs-input interruption must not park for continuation; the API call \\\n         is retried up to the timeout-retry budget, then stops\"\n    );\n\n    let interrupted = {\n        let manager = manager.read().await;\n        manager\n            .get_result(&agent_id)\n            .expect(\"agent should stay registered\")\n    };\n    assert!(matches!(interrupted.status, SubAgentStatus::Interrupted(_)));\n    let checkpoint = interrupted\n        .checkpoint\n        .as_ref()","sourceCodeStart":8997,"sourceCodeEnd":9033,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/tools/subagent/tests.rs#L8997-L9033","documentation":"Panic from `.expect(\"sub-agent task must not park waiting for checkpoint input\")`: the outer tokio timeout fired because task_handle did not complete within 5 seconds. The test pins that a needs-input interruption after an API timeout must NOT block on checkpoint continuation; parking here is the regression.","triggerScenarios":"The sub-agent task, upon receiving a needs-input interruption from the API timeout, awaits checkpoint input (e.g., joins a continuation channel) instead of exhausting SUBAGENT_API_TIMEOUT_MAX_RETRIES and finishing.","commonSituations":"A change that routes timeout interruptions into the checkpoint-parking path used for genuine user checkpoints; unbounded retry or wait added around the needs-input branch; task deadlock on an unanswered input channel.","solutions":["Ensure the needs-input/interrupted path completes the task instead of awaiting checkpoint continuation","Check no new wait was added around task_handle's inner join after interruption","Confirm retries cap at SUBAGENT_API_TIMEOUT_MAX_RETRIES + 1 attempts and then return","Raise the outer timeout only if retries legitimately exceed 5s; otherwise fix the parking"],"exampleFix":"// before\n.await.expect(\"sub-agent task must not park waiting for checkpoint input\");\n// after\n.await.unwrap_or_else(|_| panic!(\"task parked after needs-input; still running after 5s\"));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"tokio::time::timeout(Duration::from_secs(5), task_handle)\n    .await\n    .unwrap_or_else(|_| panic!(\"sub-agent parked waiting for checkpoint input\"));","preventionTips":["Keep needs-input (timeout) and user-checkpoint paths as distinct code paths","Add watchdog assertions wherever a task may wait on a channel","Never await continuation input on the automatic-retry path"],"tags":["rust","tokio","subagent","checkpoint","deadlock"],"backgroundTag":"invalid-state-transition","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}