{"record":{"id":"a9b563e95928e433","repo":"thedotmack/claude-mem","slug":"projection-timeout-must-be-a-positive-safe-integer-strictly","errorCode":null,"errorMessage":"projection timeout must be a positive safe integer strictly shorter than the Hub lease","messagePattern":"projection timeout must be a positive safe integer strictly shorter than the Hub lease","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"workers/sync-hub/src/index.ts","lineNumber":558,"sourceCode":"\tstatus: number;\n\tbodyText: string;\n}\n\nexport type ProjectionFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\n/**\n * Bound both the upstream fetch and consumption of its response body. A fetch\n * that returns headers but stalls the body must not outlive the fencing lease.\n */\nexport async function fetchProjectionWithTimeout(\n\turl: string,\n\trequestBody: string,\n\tsecret: string,\n\ttimeoutMs = PROJECTION_FETCH_TIMEOUT_MS,\n\tfetchImpl: ProjectionFetch = fetch,\n): Promise<ProjectionFetchResult> {\n\tif (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs >= PROJECTION_LEASE_MS) {\n\t\tthrow new Error(\"projection timeout must be a positive safe integer strictly shorter than the Hub lease\");\n\t}\n\tconst controller = new AbortController();\n\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\tconst deadline = new Promise<never>((_resolve, reject) => {\n\t\ttimeout = setTimeout(() => {\n\t\t\tcontroller.abort(\"projection fetch deadline exceeded\");\n\t\t\treject(new Error(\"projection_upstream_timeout\"));\n\t\t}, timeoutMs);\n\t});\n\tconst request = (async (): Promise<ProjectionFetchResult> => {\n\t\tconst response = await fetchImpl(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${secret}`,\n\t\t\t},\n\t\t\tbody: requestBody,\n\t\t\tsignal: controller.signal,","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/workers/sync-hub/src/index.ts#L540-L576","documentation":"fetchProjectionWithTimeout validates its timeoutMs argument (default PROJECTION_FETCH_TIMEOUT_MS) before starting the upstream projection fetch. The parameter must be a positive safe integer strictly below PROJECTION_LEASE_MS, because the timeout is what aborts the fetch and its body read within the Hub's fencing-lease window. The error fires only when a caller (e.g. drainProjection wiring, or a test passing a custom timeout) supplies a non-integer, zero/negative, non-safe-integer, or lease-exceeding timeout — an invalid input defect, not a runtime fetch failure.","triggerScenarios":"Thrown at workers/sync-hub/src/index.ts:558 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass a positive safe integer timeoutMs that is strictly less than PROJECTION_LEASE_MS","Omit the parameter to use the PROJECTION_FETCH_TIMEOUT_MS default, which is already validated at module load","Clamp or validate caller-supplied timeout values before invoking fetchProjectionWithTimeout","Fix test harnesses that inject timeout values exceeding the lease"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}