oven-sh/bun · error · Error

github ${path}: ${res.status}

Error message

github ${path}: ${res.status}

What it means

githubJson() in scripts/binary-size.ts throws when any GitHub REST call to api.github.com/repos/oven-sh/bun/<path> returns non-2xx. It is used to map commits to BuildKite builds and fetch baselines; auth comes from getSecret("GITHUB_TOKEN") ?? process.env.GITHUB_TOKEN.

Source

Thrown at scripts/binary-size.ts:100

  console.log(`  ${triplet.padEnd(30)} ${fmtBytes(sizes[triplet]).padStart(10)}`);
}

await Bun.write(
  "binary-sizes.json",
  JSON.stringify({ build: buildNumber, branch, release: isRelease, sizes }, null, 2),
);
agent(["artifact", "upload", "binary-sizes.json"]);

// ─── Baselines ───

type Baseline = { label: string; href?: string; sizes: Sizes };

const ghToken = (await getSecret("GITHUB_TOKEN")) ?? process.env.GITHUB_TOKEN;
const ghHeaders: Record<string, string> = ghToken ? { Authorization: `Bearer ${ghToken}` } : {};

async function githubJson<T>(path: string): Promise<T> {
  const res = await fetch(`https://api.github.com/repos/oven-sh/bun/${path}`, { headers: ghHeaders });
  if (!res.ok) throw new Error(`github ${path}: ${res.status}`);
  return res.json() as Promise<T>;
}

async function buildNumberForCommit(sha: string): Promise<number | undefined> {
  const { statuses } = await githubJson<{ statuses: { context: string; target_url: string }[] }>(
    `commits/${sha}/status`,
  );
  const bk = statuses.find(s => s.context.startsWith("buildkite/"));
  const m = bk?.target_url.match(/\/builds\/(\d+)/);
  return m ? parseInt(m[1], 10) : undefined;
}

async function sizesFromBuild(n: number): Promise<{ sizes: Sizes; release?: boolean } | undefined> {
  const res = await fetch(`https://buildkite.com/${org}/${pipeline}/builds/${n}.json`);
  if (!res.ok) return;
  const { id } = (await res.json()) as { id: string };
  const dir = "binary-size-tmp";
  rmSync(dir, { recursive: true, force: true });

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Export a valid GITHUB_TOKEN (public-repo read is sufficient)
  2. On 403/429: wait for the rate-limit window (check X-RateLimit-Reset) or use a token with a higher limit
  3. On 404: verify the commit SHA exists on oven-sh/bun
  4. Retry once after backoff for transient 5xx

Example fix

# before
$ bun scripts/binary-size.ts
Error: github commits/<sha>/status: 403

# after
$ export GITHUB_TOKEN=$(gh auth token)
$ bun scripts/binary-size.ts
Defensive patterns

Strategy: retry

Validate before calling

const r = await fetch("https://api.github.com/rate_limit", { headers: ghHeaders });
const { rate: { remaining } } = await r.json();
if (remaining === 0) throw new Error("out of GitHub rate limit; export GITHUB_TOKEN or wait");

Type guard

const isGithubApiError = (e: unknown) =>
  e instanceof Error && /^github \S+: \d{3}$/.test(e.message);

Try / catch

for (let attempt = 1; ; attempt++) {
  try { return await githubJson(path); }
  catch (e) {
    if (attempt === 3 || !isGithubApiError(e)) throw e;
    if (e.message.endsWith("404")) throw e; // permanent, not transient
    await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
  }
}

Prevention

When it happens

Trigger: 403/429 rate limiting (especially unauthenticated at 60 requests/hour), 401 from an expired or invalid token, 404 when a commit SHA or its combined status has no data, or GitHub 5xx incidents.

Common situations: Running binary-size locally without GITHUB_TOKEN exported; a CI token lacking read scope for oven-sh/bun; querying a SHA from a force-pushed branch; running during a GitHub outage.

Related errors


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