{"record":{"id":"e189559c35bb0899","repo":"can1357/oh-my-pi","slug":"openai-files-api-upload-response-has-an-invalid-by","errorCode":null,"errorMessage":"OpenAI Files API upload response has an invalid byte count","messagePattern":"OpenAI Files API upload response has an invalid byte count","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/provider-files-openai.ts","lineNumber":48,"sourceCode":"\t\t\tpathname === \"/v1\"\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction parseOpenAIFileResponse(payload: unknown): OpenAIFileResponse {\n\tconst file = payload as Partial<OpenAIFileResponse> | null;\n\tif (file === null || typeof file !== \"object\") {\n\t\tthrow new Error(\"OpenAI Files API returned an invalid upload response\");\n\t}\n\n\tconst { id, bytes, status } = file;\n\tif (typeof id !== \"string\" || id.trim().length === 0) {\n\t\tthrow new Error(\"OpenAI Files API upload response is missing a file id\");\n\t}\n\tif (typeof bytes !== \"number\" || !Number.isSafeInteger(bytes) || bytes < 0) {\n\t\tthrow new Error(\"OpenAI Files API upload response has an invalid byte count\");\n\t}\n\tif (status !== \"uploaded\" && status !== \"processed\" && status !== \"error\") {\n\t\tthrow new Error(\"OpenAI Files API upload response has an invalid status\");\n\t}\n\treturn { id, bytes, status };\n}\n\nfunction fileName(request: ProviderFileUploadRequest): string {\n\tconst preferred = request.filename?.trim().replaceAll(\"\\\\\", \"/\").split(\"/\").pop();\n\treturn preferred && preferred !== \".\" && preferred !== \"..\" ? preferred : \"image\";\n}\n\n/**\n * Create an OpenAI Files API client for an official OpenAI Responses model.\n *\n * Models using Codex, Azure, OpenRouter, or another OpenAI-compatible endpoint\n * are rejected locally by returning `null`; no request is attempted for them.\n */","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/provider-files-openai.ts#L30-L66","documentation":"Thrown by parseOpenAIFileResponse when the bytes field is not a non-negative safe integer. The library requires an accurate byte count on every upload response because it feeds size accounting and handle metadata; a missing, fractional, negative, or oversized value is rejected.","triggerScenarios":"Calling upload() when the OpenAI response's bytes field is absent, undefined, a string (\"1234\"), a float (1234.5), negative, or exceeds Number.MAX_SAFE_INTEGER — usually from a non-OpenAI-compatible gateway or hand-built mock.","commonSituations":"OpenAI-compatible servers (vLLM, LocalAI, proxies) that omit or stringify bytes; test fixtures with placeholder values; gateways returning bytes as null for unknown sizes.","solutions":["If using an OpenAI-compatible gateway, check whether it reports bytes; patch/upgrade the gateway or compute bytes client-side from the uploaded payload.","Inspect the raw response and coerce a numeric string before parsing if the gateway is known to stringify numbers.","Update test fixtures to use real integer byte counts from actual OpenAI responses.","Report/fix the gateway bug — the official OpenAI Files API always returns an integer bytes value."],"exampleFix":"// before\ntypeGuardParse(body); // body.bytes = \"1536\"\n// after: normalize gateway response\nconst fixed = { ...body, bytes: Number(body.bytes) };\nconst parsed = parseOpenAIFileResponse(fixed);","handlingStrategy":"validation","validationCode":"const bytes = (body as { bytes?: unknown }).bytes;\nif (typeof bytes === \"string\" && /^\\d+$/.test(bytes)) body.bytes = Number(bytes);\nif (typeof body.bytes !== \"number\" || !Number.isSafeInteger(body.bytes) || body.bytes < 0) {\n  throw new Error(`gateway returned unusable bytes: ${String(bytes)}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize numeric strings from gateways before parsing","For gateways that omit bytes, compute the size client-side from the uploaded payload","Fix test fixtures to use integer byte counts","Report schema drift in OpenAI-compatible servers you depend on"],"tags":["validation","openai","file-upload","response-parsing","schema-validation-failed"],"backgroundTag":"invalid-api-response-shape","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}