can1357/oh-my-pi · error · Error
AI staging request failed: ${response.errorMessage ?? "unkno
Error message
AI staging request failed: ${response.errorMessage ?? "unknown error"} What it means
The completer sends the user prompt plus file diffs to the selected model and checks the response's stopReason. A stopReason of "error" means the provider request failed; the raw errorMessage (or "unknown error") is wrapped in this error. This surfaces upstream API failures (rate limits, invalid key, server errors, aborts) to the AI-stage caller.
Source
Thrown at packages/coding-agent/src/cli/git-tui/ai-stage.ts:235
/** One text completion against the resolved model. */
function createCompleter(
model: Model<Api>,
apiKey: ApiKey,
signal?: AbortSignal,
): (userPrompt: string) => Promise<string> {
return async userPrompt => {
const response = await retryTransientCompletion(
() =>
completeSimple(
model,
{ messages: [{ role: "user", content: userPrompt, timestamp: Date.now() }] },
{ apiKey, maxTokens: SAFE_MAX_TOKENS, temperature: 0, disableReasoning: true, signal },
),
{ signal },
);
if (response.stopReason === "error") {
throw new Error(`AI staging request failed: ${response.errorMessage ?? "unknown error"}`);
}
return extractText(response.content);
};
}
/**
* Fan out one judgement per item. A failed judgement rejects just its item so
* one flaky request cannot sink the run — unless every item failed, which
* means the backend is broken and the first error surfaces.
*/
async function judgeAll<T>(items: readonly T[], run: (item: T) => Promise<boolean>): Promise<boolean[]> {
let failures = 0;
let firstError: unknown;
const verdicts = await Promise.all(
items.map(async item => {
try {
return await run(item);
} catch (error) {View on GitHub (pinned to 9690622007)
Solutions
- Read the wrapped errorMessage to identify the cause (401 → fix key, 429 → retry later).
- Retry the staging command; transient rate limits and outages resolve on their own.
- Re-authenticate or update the provider API key.
- Reduce diff size (stage fewer files at once) if the request is being rejected for size/token limits.
Example fix
// before
await aiStage(opts); // surfaces raw provider error
// after
try { await aiStage(opts); }
catch (e) {
if (String(e.message).includes("429")) await Bun.sleep(5000), retry();
else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
// preflight reachability/auth
const res = await fetch(`${providerBaseUrl}/models`, { headers: { Authorization: `Bearer ${apiKey}` } });
if (!res.ok) throw new Error(`Provider preflight failed: ${res.status}`); Try / catch
try {
await aiStage(opts);
} catch (e) {
const msg = e instanceof Error ? e.message : "";
if (msg.includes("AI staging request failed") && (msg.includes("429") || msg.includes("503"))) {
await Bun.sleep(5000);
return aiStage(opts); // one retry for transient errors
}
throw e;
} Prevention
- Keep API keys valid/rotated to avoid 401s.
- Add exponential backoff for 429/5xx in automated staging flows.
- Keep diffs small; split large change sets into multiple staging runs.
- Verify network/proxy access to the provider endpoint in CI.
When it happens
Trigger: The LLM stream completes with response.stopReason === "error" — e.g. HTTP 401 (invalid key), 429 (rate limit), 5xx provider outage, network failure mid-request, or a signal abort reported as an error.
Common situations: Expired or revoked API key, exceeding provider rate limits with large diffs, provider outage, or corporate proxy blocking the endpoint.
Related errors
- V2 remote compaction failed (${response.status} ${response.s
- Devin API error ${response.status} ${response.statusText}: $
- HTTP request failed. status=${response.status}; url=${url};
- Checker discovery failed: ${result.result.error}
- ${response.errorMessage ?? "provider error"}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/056874fb8a0bf57c.
Report an issue: GitHub.