{"record":{"id":"8d4962126eaef5e7","repo":"can1357/oh-my-pi","slug":"operation-request-timed-out-after-math-round","errorCode":null,"errorMessage":"${operation} request timed out after ${Math.round(timeoutMs / 1000)}s / ${operation} request failed: ${err instanceof Error ? err.message : String(err)}","messagePattern":"(.+?) request timed out after (.+?)s / (.+?) request failed: (.+?)","errorType":"exception","errorClass":"HindsightError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/hindsight/client.ts","lineNumber":556,"sourceCode":"\n\t\tconst timeoutMs = opts?.timeoutMs ?? this.#requestTimeoutMs;\n\t\tconst init: RequestInit = {\n\t\t\tmethod,\n\t\t\theaders: this.#headers,\n\t\t\tsignal: withTimeoutSignal(timeoutMs, opts?.signal),\n\t\t};\n\t\tif (opts?.body !== undefined) {\n\t\t\tinit.body = JSON.stringify(pruneUndefined(opts.body));\n\t\t}\n\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(url, init);\n\t\t} catch (err) {\n\t\t\tconst message = isTimeoutError(err)\n\t\t\t\t? `${operation} request timed out after ${Math.round(timeoutMs / 1000)}s`\n\t\t\t\t: `${operation} request failed: ${err instanceof Error ? err.message : String(err)}`;\n\t\t\tthrow new HindsightError(message, undefined, err);\n\t\t}\n\n\t\tif (opts?.allow404 && response.status === 404) {\n\t\t\treturn null as T;\n\t\t}\n\n\t\tconst text = await response.text();\n\t\tconst parsed = text ? safeJsonParse(text) : null;\n\n\t\tif (!response.ok) {\n\t\t\tconst details =\n\t\t\t\t(parsed && typeof parsed === \"object\"\n\t\t\t\t\t? ((parsed as { detail?: unknown; message?: unknown }).detail ??\n\t\t\t\t\t\t(parsed as { message?: unknown }).message)\n\t\t\t\t\t: undefined) ??\n\t\t\t\tparsed ??\n\t\t\t\ttext;\n\t\t\tthrow new HindsightError(","sourceCodeStart":538,"sourceCodeEnd":574,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/hindsight/client.ts#L538-L574","documentation":"HindsightClient.#request wraps fetch failures in a HindsightError. If the thrown error is a timeout (isTimeoutError) the message reports that `operation` timed out after timeoutMs; otherwise it reports the underlying network error message. The original error is attached as cause.","triggerScenarios":"Calling retain/retainBatch/recall/reflect/createBank/listMemories when the Hindsight server is unreachable (ECONNREFUSED, DNS failure, connection reset) or does not respond within the configured timeout.","commonSituations":"Hindsight service not running or wrong base URL/port; server slow or overloaded exceeding the client timeout; firewall or network outage in containers/CI; TLS failures.","solutions":["Confirm the Hindsight server is running and reachable at the configured URL (curl the health endpoint)","Increase the client timeout if operations are legitimately slow","Check DNS/proxy/firewall settings, especially in Docker or CI environments","Retry idempotent operations with backoff; check the cause on HindsightError for the root network error"],"exampleFix":"// before\nconst client = new HindsightClient({ baseUrl: \"http://localhost:9100\", timeoutMs: 5000 });\n// after\nconst client = new HindsightClient({ baseUrl: \"http://localhost:9100\", timeoutMs: 30000 });\ntry {\n  await client.retain(\"...\");\n} catch (err) {\n  if (err instanceof HindsightError && err.cause) console.error(err.cause);\n  throw err;\n}","handlingStrategy":"retry","validationCode":"// preflight reachability\nconst res = await fetch(`${baseUrl}/health`, { signal: AbortSignal.timeout(3000) });\nif (!res.ok) throw new Error(`Hindsight unreachable: ${res.status}`);","typeGuard":"function isHindsightTimeout(err: unknown): err is HindsightError {\n  return err instanceof HindsightError && /timed out after/.test(err.message);\n}","tryCatchPattern":"try {\n  await client.recall(query);\n} catch (err) {\n  if (err instanceof HindsightError && /timed out after/.test(err.message)) {\n    await Bun.sleep(1000);\n    return client.recall(query); // bounded retry with backoff\n  }\n  throw err;\n}","preventionTips":["Set a timeout appropriate to worst-case operation latency","Monitor Hindsight service health; alert on connection failures","Log err.cause to distinguish timeout vs DNS vs refused connections","Use retries with exponential backoff for idempotent operations"],"tags":["network","timeout","http-client"],"backgroundTag":"request-timeout","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}