can1357/oh-my-pi · error

OpenAI Files API upload response is missing a file id

Error message

OpenAI Files API upload response is missing a file id

What it means

Thrown by parseOpenAIFileResponse when the uploaded-file object lacks an id field that is a non-empty string. The id is the primary key for all subsequent Files API operations (retrieve, delete, attaching to requests), so the library refuses to return a handle without it.

Source

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

			baseUrl.password === "" &&
			baseUrl.search === "" &&
			baseUrl.hash === "" &&
			pathname === "/v1"
		);
	} catch {
		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.
 *

View on GitHub (pinned to 9690622007)

Solutions

  1. Dump the full response body to confirm the id field is present and named id.
  2. If using an OpenAI-compatible gateway, check whether it wraps the file in another envelope (e.g. {data: {...}}) and unwrap before passing through.
  3. Pin/verify the OpenAI API version your gateway proxies — older/newer versions may change the schema.
  4. Ensure the upload actually succeeded (check HTTP status and that no error object was returned) before parsing.
  5. In tests, use realistic fixtures copied from real OpenAI upload responses.

Example fix

// before: gateway returns envelope
const parsed = parseOpenAIFileResponse(body); // body = { data: { id: ... } }
// after: unwrap first
const file = "data" in body && body.data ? body.data : body;
const parsed = parseOpenAIFileResponse(file);
Defensive patterns

Strategy: type-guard

Validate before calling

const body = await res.json();
const file = "data" in body && isObject(body.data) ? body.data : body;
if (typeof file?.id !== "string" || file.id.trim() === "") {
  throw new Error(`upload response has no usable id: ${JSON.stringify(body).slice(0, 200)}`);
}

Type guard

function hasFileId(v: unknown): v is { id: string } & Record<string, unknown> {
  return isObject(v) && typeof v.id === "string" && v.id.trim().length > 0;
}

Try / catch

try {
  const handle = await openaiClient.upload(request);
} catch (err) {
  if (String(err?.message).includes("missing a file id")) {
    throw new Error("gateway response missing file id — unwrap {data:{...}} envelope or check API version");
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling upload() when OpenAI's response object has no id, an empty/whitespace id, or id of a non-string type — typically from a differently-shaped error/edge response or a mis-mapped proxy response.

Common situations: Proxy or OpenAI-compatible gateway returning partial objects; mocked responses in tests missing fields; upstream API version change altering the field name (e.g. nesting under data); response from a failed upload that returns an object without id.

Related errors


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