can1357/oh-my-pi · error

OpenAI Files API upload response has an invalid status

Error message

OpenAI Files API upload response has an invalid status

What it means

Thrown by parseOpenAIFileResponse when the status field is not one of the accepted values "uploaded", "processed", or "error". The library whitelists the known OpenAI file statuses; anything else (missing, different casing, or gateway-specific values like "completed" or "pending") is rejected because downstream logic branches on these exact strings.

Source

Thrown at packages/coding-agent/src/blob-broker/provider-files-openai.ts:51

		return false;
	}
}

function parseOpenAIFileResponse(payload: unknown): OpenAIFileResponse {
	const file = payload as Partial<OpenAIFileResponse> | null;
	if (file === null || typeof file !== "object") {
		throw new Error("OpenAI Files API returned an invalid upload response");
	}

	const { id, bytes, status } = file;
	if (typeof id !== "string" || id.trim().length === 0) {
		throw new Error("OpenAI Files API upload response is missing a file id");
	}
	if (typeof bytes !== "number" || !Number.isSafeInteger(bytes) || bytes < 0) {
		throw new Error("OpenAI Files API upload response has an invalid byte count");
	}
	if (status !== "uploaded" && status !== "processed" && status !== "error") {
		throw new Error("OpenAI Files API upload response has an invalid status");
	}
	return { id, bytes, status };
}

function fileName(request: ProviderFileUploadRequest): string {
	const preferred = request.filename?.trim().replaceAll("\\", "/").split("/").pop();
	return preferred && preferred !== "." && preferred !== ".." ? preferred : "image";
}

/**
 * Create an OpenAI Files API client for an official OpenAI Responses model.
 *
 * Models using Codex, Azure, OpenRouter, or another OpenAI-compatible endpoint
 * are rejected locally by returning `null`; no request is attempted for them.
 */
export function createOpenAIFileClient(
	model: Model,
	credential: string,

View on GitHub (pinned to 9690622007)

Solutions

  1. Compare the raw response's status against the accepted set and map gateway-specific values (e.g. "completed" → "processed") before parsing.
  2. If the gateway reports an intermediate status, poll the file retrieve endpoint until it reaches a terminal state.
  3. Upgrade the OpenAI-compatible gateway to one matching the official Files API status values.
  4. Check for casing differences and normalize with String(status).toLowerCase() only if you control the mapping both ways.
  5. Update mocked test fixtures to use exactly "uploaded", "processed", or "error".

Example fix

// before: gateway says "completed"
const parsed = parseOpenAIFileResponse(body); // throws
// after: map known aliases
const aliases: Record<string, string> = { completed: "processed", ok: "processed" };
const parsed = parseOpenAIFileResponse({
  ...body,
  status: aliases[body.status] ?? body.status,
});
Defensive patterns

Strategy: validation

Validate before calling

const ACCEPTED = new Set(["uploaded", "processed", "error"]);
if (typeof body.status !== "string" || !ACCEPTED.has(body.status)) {
  throw new Error(`unsupported file status: ${String(body.status)}`);
}

Type guard

function hasKnownFileStatus(v: unknown): v is { status: "uploaded" | "processed" | "error" } & Record<string, unknown> {
  return isObject(v) && (v.status === "uploaded" || v.status === "processed" || v.status === "error");
}

Prevention

When it happens

Trigger: Calling upload() when the response status field is absent, an unexpected value such as "pending", "completed", "failed", or different casing ("Uploaded") — most common with OpenAI-compatible gateways or batch/asynchronous upload flows that report intermediate states.

Common situations: Using an OpenAI-compatible server that emits its own status vocabulary; proxies that lowercase/transform fields; uploading to an endpoint that returns the pre-processing state; outdated gateway versions predating these status values.

Related errors


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