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

  1. Read the status and body in the message to classify (404-expired vs 401-permission vs 5xx)
  2. For 404, re-query the target resource's provisioningState instead of the dead operation URL
  3. For 401/403, grant the identity read access to the resource the operation belongs to
  4. 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

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


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/617c755ed5b6010d. Report an issue: GitHub.