{"record":{"id":"90a65363213ce289","repo":"paperclipai/paperclip","slug":"question-response-delivery-claim-unavailable","errorCode":null,"errorMessage":"question_response_delivery_claim_unavailable","messagePattern":"question_response_delivery_claim_unavailable","errorType":"exception","errorClass":"DeliveryClaimUnavailableError","httpStatus":null,"severity":"error","filePath":"server/src/services/question-response-delivery.ts","lineNumber":693,"sourceCode":"        .from(issueQuestionResponseDeliveries)\n        .where(\n          and(\n            eq(issueQuestionResponseDeliveries.id, delivery.id),\n            eq(issueQuestionResponseDeliveries.status, \"delivering\"),\n            eq(\n              issueQuestionResponseDeliveries.attemptCount,\n              delivery.attemptCount,\n            ),\n          ),\n        )\n        .limit(1)\n        .then((rows) => rows.length === 1);\n    } catch (error) {\n      logger.warn(\n        { err: error, deliveryId: delivery.id },\n        \"question response claim ownership check failed\",\n      );\n      throw new DeliveryClaimUnavailableError();\n    }\n    if (!ownsClaim) throw new DeliveryClaimUnavailableError();\n    if (operationError !== undefined) throw operationError;\n    return result as T;\n  }\n\n  async function findDurableWakeRequest(input: {\n    companyId: string;\n    idempotencyKey: string;\n  }) {\n    const request = await db\n      .select({\n        agentId: agentWakeupRequests.agentId,\n        id: agentWakeupRequests.id,\n        runId: agentWakeupRequests.runId,\n        status: agentWakeupRequests.status,\n      })\n      .from(agentWakeupRequests)","sourceCodeStart":675,"sourceCodeEnd":711,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/question-response-delivery.ts#L675-L711","documentation":"DeliveryClaimUnavailableError from withClaimLease: the claim ownership check against the database failed (an exception occurred while verifying rows.length === 1). The delivery's claim lease could not be confirmed, so the operation aborts to avoid two workers processing the same delivery. It is deliberately thrown instead of proceeding on uncertain ownership.","triggerScenarios":"Inside withClaimLease, the ownership SELECT/UPDATE throws (DB connection failure, timeout, serialization error) so ownsClaim cannot be determined; the catch block logs 'question response claim ownership check failed' and rethrows as DeliveryClaimUnavailableError.","commonSituations":"Transient Postgres connectivity loss during delivery; statement timeout on the claim check; DB failover mid-delivery; heavy lock contention on the delivery row.","solutions":["Retry the delivery operation after a short backoff — the error signals an uncertain claim, not a permanent failure","Verify database connectivity and check server logs for the correlated 'question response claim ownership check failed' warning","Check for lock contention or long transactions holding the delivery row","If persistent, inspect DB health (max_connections, statement_timeout) and the claim lease query"],"exampleFix":"// before\nawait withClaimLease(deliveryId, doDeliver); // throws on transient DB hiccup\n// after\nawait retry(\n  { retries: 3, factor: 2 },\n  () => withClaimLease(deliveryId, doDeliver),\n  { shouldRetry: (e) => e instanceof DeliveryClaimUnavailableError },\n);","handlingStrategy":"retry","validationCode":"// Pre-check DB reachability before delivery batch\nconst ok = await db.execute(sql`SELECT 1`).then(() => true, () => false);\nif (!ok) await waitForDbHealth();","typeGuard":"function isDeliveryClaimUnavailable(e) {\n  return e instanceof Error && (e.name === \"DeliveryClaimUnavailableError\" || e.message === \"question_response_delivery_claim_unavailable\");\n}","tryCatchPattern":"try {\n  await withClaimLease(deliveryId, operation);\n} catch (e) {\n  if (isDeliveryClaimUnavailable(e)) {\n    // uncertain ownership (db check failed): safe to retry with backoff\n    await backoff(retryCount++);\n    return retryDelivery(deliveryId);\n  }\n  throw e;\n}","preventionTips":["Keep DB connections healthy (pool limits, statement_timeout tuned) so the ownership check does not fail spuriously","Wrap claim-dependent work in bounded retries with exponential backoff","Alert on repeated 'question response claim ownership check failed' warnings","Avoid running delivery inside long transactions that hold locks on the delivery row"],"tags":["database","concurrency","claim-lease"],"backgroundTag":"database-query-failed","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}