can1357/oh-my-pi · error · AIError.ProviderHttpError

HTTP request failed. status=${response.status}; url=${url};

Error message

HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}

What it means

getJson performs a GET against a Z.ai business endpoint with a 30s timeout and throws AIError.ProviderHttpError when the HTTP status is not ok, including the status, URL, and raw response body. This is a transport/HTTP-level failure surfaced from the Z.ai REST API.

Source

Thrown at packages/ai/src/registry/oauth/zai.ts:77

			throw new AIError.OAuthError(`Z.ai ${operation} failed: ${envelope.msg ?? `code ${String(envelope.code)}`}`, {
				kind: "token-exchange",
				provider: "zai",
			});
		}
		return "data" in envelope ? envelope.data : envelope;
	}
	return body;
}

async function getJson(url: string, headers: Record<string, string>, fetchImpl: FetchImpl): Promise<unknown> {
	const response = await fetchImpl(url, {
		method: "GET",
		headers,
		signal: AbortSignal.timeout(30_000),
	});
	const responseBody = await response.text();
	if (!response.ok) {
		throw new AIError.ProviderHttpError(
			`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`,
			response.status,
		);
	}
	return responseBody.length > 0 ? JSON.parse(responseBody) : undefined;
}

async function postJson(
	url: string,
	body: Record<string, string | number>,
	headers: Record<string, string>,
	fetchImpl: FetchImpl,
): Promise<unknown> {
	const response = await fetchImpl(url, {
		method: "POST",
		headers: { ...headers, "Content-Type": "application/json" },
		body: JSON.stringify(body),
		signal: AbortSignal.timeout(30_000),

View on GitHub (pinned to 9690622007)

Solutions

  1. Inspect status and body in the ProviderHttpError: 401/403 → refresh the business token via business login; 404 → verify organizationId/projectId/apiKey; 429/5xx → back off and retry.
  2. Re-authenticate the Z.ai business token and retry the GET.
  3. Confirm the correct regional BIZ_BASE URL for the account.
  4. Wrap calls in retry with exponential backoff for transient 429/5xx statuses.

Example fix

// before
const orgs = await getJson(ORGS_URL, auth, fetch);
// after
let orgs;
try { orgs = await getJson(ORGS_URL, auth, fetch); }
catch (e) {
  if (e instanceof AIError.ProviderHttpError && (e.status === 429 || e.status >= 500)) { await Bun.sleep(1000); orgs = await getJson(ORGS_URL, auth, fetch); }
  else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

if (!bizToken || typeof bizToken !== "string") throw new Error("Refusing GET: missing Z.ai business token");

Try / catch

try { return await getJson(url, auth, fetch); }
catch (e) {
  if (e instanceof AIError.ProviderHttpError && (e.status === 429 || e.status >= 500) && attempt < 3) { await Bun.sleep(2 ** attempt * 500); return retry(); }
  throw e;
}

Prevention

When it happens

Trigger: GET to org/project list or api key copy endpoint returns 401/403/404/429/5xx; the copy endpoint path contains a malformed apiKey; auth headers carry an invalid biz token; network middleboxes return error pages.

Common situations: Expired business token causing 401; wrong BIZ_BASE region host; Z.ai API returns 429 under rate limiting; copy endpoint 404 because the key was deleted concurrently.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f39f10b767583015. Report an issue: GitHub.