{"record":{"id":"594b30aad40ac13d","repo":"nanocoai/nanoclaw","slug":"killing-container-message-claimed-then-silent","errorCode":null,"errorMessage":"Killing container — message claimed then silent","messagePattern":"Killing container — message claimed then silent","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/host-sweep.ts","lineNumber":286,"sourceCode":"    containerStartedAtMs: getContainerStartedAtMs(session.id),\n    containerState: outDb.getContainerState(),\n    claims: outDb.getProcessingClaims(),\n  });\n\n  if (decision.action === 'ok') return;\n\n  if (decision.action === 'kill-ceiling') {\n    log.warn('Killing container past absolute ceiling', {\n      sessionId: session.id,\n      heartbeatAgeMs: decision.heartbeatAgeMs,\n      ceilingMs: decision.ceilingMs,\n    });\n    killContainer(session.id, 'absolute-ceiling');\n    resetStuckProcessingRows(inDb, outDb, session, 'absolute-ceiling');\n    return;\n  }\n\n  log.warn('Killing container — message claimed then silent', {\n    sessionId: session.id,\n    messageId: decision.messageId,\n    claimAgeMs: decision.claimAgeMs,\n    toleranceMs: decision.toleranceMs,\n  });\n  killContainer(session.id, 'claim-stuck');\n  resetStuckProcessingRows(inDb, outDb, session, 'claim-stuck');\n}\n\nexport function _resetStuckProcessingRowsForTesting(\n  inDb: InboundMailbox,\n  outDb: OutboundMailbox,\n  session: Session,\n  reason: string,\n): void {\n  resetStuckProcessingRows(inDb, outDb, session, reason);\n}\n","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/host-sweep.ts#L268-L304","documentation":"The sweep kills a container because it claimed a message in processing_ack and then went silent longer than the claim tolerance. Unlike the absolute-ceiling kill, the heartbeat may still be fresh but a specific claimed message has made no progress, indicating a wedged agent run rather than a dead container.","triggerScenarios":"A processing_ack row exists with claimAgeMs > toleranceMs while the container is running; killContainer(session.id, 'claim-stuck') fires and the claimed row is reset.","commonSituations":"Agent-runner stuck mid-inference or in a tool loop on one message; provider API hang without timeout; agent process alive (heartbeat touched by a loop) but the message handler deadlocked.","solutions":["Inspect the session's outbound.db processing_ack and the specific messageId to see which request stalled","Check provider/API latency or hangs from the container (network, proxy, OneCLI gateway) around the claim time","Tune the claim tolerance if legitimate long-running turns exceed it","Confirm the reset row was retried by the respawned container rather than looping into the same stall"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set provider/API timeouts shorter than the claim tolerance so hung calls fail fast","Watch processing_ack age as a metric; investigate before the sweep kills","Tune toleranceMs to comfortably exceed your longest legitimate agent turn"],"tags":["sweep","claim-stuck","processing-ack","container-kill"],"backgroundTag":"stuck-message-claim","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}