can1357/oh-my-pi · error · HindsightError

${operation} request timed out after ${Math.round(timeoutMs

Error message

${operation} request timed out after ${Math.round(timeoutMs / 1000)}s / ${operation} request failed: ${err instanceof Error ? err.message : String(err)}

What it means

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.

Source

Thrown at packages/coding-agent/src/hindsight/client.ts:556

		const timeoutMs = opts?.timeoutMs ?? this.#requestTimeoutMs;
		const init: RequestInit = {
			method,
			headers: this.#headers,
			signal: withTimeoutSignal(timeoutMs, opts?.signal),
		};
		if (opts?.body !== undefined) {
			init.body = JSON.stringify(pruneUndefined(opts.body));
		}

		let response: Response;
		try {
			response = await fetch(url, init);
		} catch (err) {
			const message = isTimeoutError(err)
				? `${operation} request timed out after ${Math.round(timeoutMs / 1000)}s`
				: `${operation} request failed: ${err instanceof Error ? err.message : String(err)}`;
			throw new HindsightError(message, undefined, err);
		}

		if (opts?.allow404 && response.status === 404) {
			return null as T;
		}

		const text = await response.text();
		const parsed = text ? safeJsonParse(text) : null;

		if (!response.ok) {
			const details =
				(parsed && typeof parsed === "object"
					? ((parsed as { detail?: unknown; message?: unknown }).detail ??
						(parsed as { message?: unknown }).message)
					: undefined) ??
				parsed ??
				text;
			throw new HindsightError(

View on GitHub (pinned to 9690622007)

Solutions

  1. Confirm the Hindsight server is running and reachable at the configured URL (curl the health endpoint)
  2. Increase the client timeout if operations are legitimately slow
  3. Check DNS/proxy/firewall settings, especially in Docker or CI environments
  4. Retry idempotent operations with backoff; check the cause on HindsightError for the root network error

Example fix

// before
const client = new HindsightClient({ baseUrl: "http://localhost:9100", timeoutMs: 5000 });
// after
const client = new HindsightClient({ baseUrl: "http://localhost:9100", timeoutMs: 30000 });
try {
  await client.retain("...");
} catch (err) {
  if (err instanceof HindsightError && err.cause) console.error(err.cause);
  throw err;
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight reachability
const res = await fetch(`${baseUrl}/health`, { signal: AbortSignal.timeout(3000) });
if (!res.ok) throw new Error(`Hindsight unreachable: ${res.status}`);

Type guard

function isHindsightTimeout(err: unknown): err is HindsightError {
  return err instanceof HindsightError && /timed out after/.test(err.message);
}

Try / catch

try {
  await client.recall(query);
} catch (err) {
  if (err instanceof HindsightError && /timed out after/.test(err.message)) {
    await Bun.sleep(1000);
    return client.recall(query); // bounded retry with backoff
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/8d4962126eaef5e7. Report an issue: GitHub.