can1357/oh-my-pi · error · HindsightError
${operation} failed: ${typeof details === "string" ? details
Error message
${operation} failed: ${typeof details === "string" ? details : JSON.stringify(details)} What it means
HindsightClient.#request converts non-OK HTTP responses into a HindsightError. It extracts a detail/message field from the parsed JSON body (or falls back to raw text) and formats `${operation} failed: <details>`, including the HTTP status code on the error object.
Source
Thrown at packages/coding-agent/src/hindsight/client.ts:574
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(
`${operation} failed: ${typeof details === "string" ? details : JSON.stringify(details)}`,
response.status,
details,
);
}
return (parsed ?? {}) as T;
}
}
interface BuiltMemoryItem {
content: string;
timestamp?: string;
context?: string;
metadata?: Record<string, string>;
document_id?: string;
tags?: string[];
observation_scopes?: "per_tag" | "combined" | "all_combinations" | string[][];View on GitHub (pinned to 9690622007)
Solutions
- Read the HindsightError status and details fields — they carry the server's own explanation
- Fix the request payload per the server validation message (400)
- Check API credentials/auth configuration (401/403)
- Verify client and server versions are compatible if the route 404s
Example fix
// before
await client.retain({ /* wrong shape */ });
// after
try {
await client.retain({ content: "...", context: "..." });
} catch (err) {
if (err instanceof HindsightError && err.status === 400) {
console.error("Server said:", err.details);
}
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate payload shape before sending
if (typeof body.content !== "string" || body.content.length === 0) {
throw new Error("retain requires non-empty content");
} Type guard
function isApiRejection(err: unknown): err is HindsightError & { status: number } {
return err instanceof HindsightError && typeof err.status === "number";
} Try / catch
try {
await client.retain(payload);
} catch (err) {
if (err instanceof HindsightError && err.status) {
logger.error("Hindsight operation rejected", { status: err.status, details: err.details });
if (err.status >= 500) /* retry */; else /* fix request */;
} else throw err;
} Prevention
- Match request payloads to the server's current API version
- Check auth credentials on 401/403 statuses
- Surface err.details (server validation message) in logs
- Handle 404 with allow404 for optional lookups
When it happens
Trigger: Any Hindsight API call (retain, recall, reflect, createBank, listMemories) receiving a 4xx/5xx response: invalid request payload (400), auth failure (401/403), unknown bank (404 without allow404), or server error (500).
Common situations: Malformed retain payload rejected by server validation; expired or missing API credentials; calling an endpoint/route that doesn't exist on the deployed server version; upstream server crash.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- HTTP request failed. status=${response.status}; url=${url};
- V2 remote compaction failed (${response.status} ${response.s
- sso-role
- Devin API error ${response.status} ${response.statusText}: $
- ${response.status} ${response.statusText}: ${text}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f99a9f43cc25d36d.
Report an issue: GitHub.