oven-sh/bun · error · Error
[azure] Operation poll failed: ${response.status} ${await re
Error message
[azure] Operation poll failed: ${response.status} ${await response.text()} What it means
A poll request to the Azure async-operation URL completed at the HTTP layer but returned a non-2xx status; the status and body are surfaced. Unlike the fetch-error path, the server answered and rejected the poll — the token is refreshed each iteration, so stale-token 401s are less likely but Authorization failures for the operation URL still land here.
Source
Thrown at scripts/azure.mjs:169
const token = await getAccessToken();
let response;
try {
response = await fetch(operationUrl, {
headers: { Authorization: `Bearer ${token}` },
});
} catch (err) {
fetchErrors++;
if (fetchErrors > 10) {
throw new Error(`[azure] Operation poll failed after ${fetchErrors} fetch errors`, { cause: err });
}
console.warn(`[azure] Operation poll fetch error (${fetchErrors}), retrying...`);
await new Promise(r => setTimeout(r, 10_000));
continue;
}
if (!response.ok) {
throw new Error(`[azure] Operation poll failed: ${response.status} ${await response.text()}`);
}
const data = await response.json();
if (data.status === "Succeeded") {
return data.properties?.output ?? data;
}
if (data.status === "Failed" || data.status === "Canceled") {
throw new Error(`[azure] Operation ${data.status}: ${data.error?.message ?? "unknown"}`);
}
await new Promise(r => setTimeout(r, 5000));
}
throw new Error(`[azure] Operation timed out after ${maxWaitMs}ms`);
}
// ============================================================================View on GitHub (pinned to 8c5296ac45)
Solutions
- Read the status and body in the message to classify (404-expired vs 401-permission vs 5xx)
- For 404, re-query the target resource's provisioningState instead of the dead operation URL
- For 401/403, grant the identity read access to the resource the operation belongs to
- Re-run the original operation if it cannot be recovered
Example fix
// before
if (!response.ok) {
throw new Error(`[azure] Operation poll failed: ${response.status} ${await response.text()}`);
}
// after
if (!response.ok) {
if (response.status === 404) {
console.warn('operation URL expired; falling back to resource state');
return { status: 'Unknown' };
}
throw new Error(`[azure] Operation poll failed: ${response.status} ${await response.text()}`);
} Defensive patterns
Strategy: retry
Validate before calling
null
Prevention
- Persist the resource id alongside the operation URL so a 404-expired poll can fall back to provisioningState
- Poll promptly after submission; Azure retains operation records only briefly after completion
- Keep token permissions valid for the whole poll window
When it happens
Trigger: 404 when the async operation URL expired (Azure retains operation records only briefly after completion); 401/403 when the identity lacks read on the operation resource; transient 5xx from the poll endpoint not covered by retry.
Common situations: Job resumed/retried long after the operation finished, so the operation URL is gone; permission change mid-poll.
Related errors
- [azure] ${method} ${path} failed: ${response.status} ${text}
- Failed to fetch Sentry event: ${response.statusText}
- Failed to fetch Sentry issue: ${issueResponse.statusText}
- GitHub API request failed: ${response.status} ${response.sta
- [azure] Operation poll failed after ${fetchErrors} fetch err
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/617c755ed5b6010d.
Report an issue: GitHub.