{"record":{"id":"9ed58754a2e0b9da","repo":"HeyPuter/puter","slug":"upstream-bad-request","errorCode":"upstream_bad_request","errorMessage":"Together AI response did not include image data","messagePattern":"Together AI response did not include image data","errorType":"http","errorClass":"HttpError","httpStatus":400,"severity":"error","filePath":"src/backend/drivers/ai-image/providers/together/TogetherImageProvider.ts","lineNumber":194,"sourceCode":"                selectedModel.resolution_map[ratioKey]?.[quality];\n            if (resolutionEntry) {\n                resolvedRatio = resolutionEntry;\n            }\n        }\n\n        const request = this.#buildRequest(prompt, {\n            ...options,\n            ratio: resolvedRatio,\n            model: selectedModel.id.replace('togetherai:', ''),\n        }) as unknown as Together.Images.ImageGenerateParams;\n\n        // Let SDK errors bubble — together-ai SDK errors carry `.status`\n        // which the driver-boundary `translateProviderError` maps to\n        // `upstream_*` HttpErrors. Re-wrapping in `new Error(...)` would\n        // strip the status field and cause these to surface as 500s.\n        const response = await this.#client.images.generate(request);\n        if (!response?.data?.length) {\n            throw new HttpError(\n                400,\n                'Together AI response did not include image data',\n                {\n                    legacyCode: 'upstream_bad_request',\n                    fields: { provider: 'together' },\n                },\n            );\n        }\n\n        this.#meteringService.incrementUsage(\n            actor,\n            usageType,\n            usageAmount,\n            costInMicroCents,\n        );\n\n        const first = response.data[0] as {\n            url?: string;","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/drivers/ai-image/providers/together/TogetherImageProvider.ts#L176-L212","documentation":"After a successful call to this.#client.images.generate(request), the Together AI SDK returned a response object, but its data array is missing or empty. This means Together accepted the request and returned an HTTP success, but the response body did not contain image data — typically indicating an upstream model error or an API contract change.","triggerScenarios":"Together AI returns a 200 with an empty data array; the response shape changed in a newer SDK version; the model is temporarily unavailable and returns an empty result instead of an error status; the response was truncated or malformed by a proxy.","commonSituations":"Transient Together AI platform issues where the model fails silently; a model deprecation where the endpoint returns success but no data; SDK version mismatch causing response parsing differences.","solutions":["Retry the request after a brief delay — transient upstream issues often resolve.","Check the Together AI status page for ongoing incidents.","Log the full response object (including any error/message fields Together may include) for diagnosis.","Verify the together-ai SDK version is compatible with the current API contract."],"exampleFix":"// before — single call, no retry\nconst response = await this.#client.images.generate(request);\n\n// after — retry with backoff for transient upstream issues\nasync function generateWithRetry(client, request, maxRetries = 2) {\n  for (let i = 0; i <= maxRetries; i++) {\n    const response = await client.images.generate(request);\n    if (response?.data?.length) return response;\n    if (i < maxRetries) await new Promise(r => setTimeout(r, 1000 * (i + 1)));\n  }\n  throw new Error('Together AI returned empty data after retries');\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"const MAX_RETRIES = 2;\nlet lastError;\nfor (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n  try {\n    const response = await this.#client.images.generate(request);\n    if (response?.data?.length) return response;\n    lastError = new HttpError(400, 'Together AI returned empty data', { legacyCode: 'upstream_bad_request' });\n  } catch (e) {\n    lastError = e;\n  }\n  if (attempt < MAX_RETRIES) {\n    await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));\n  }\n}\nthrow lastError;","preventionTips":["Implement retry with exponential backoff for Together AI calls.","Monitor Together AI status pages for incidents.","Log full response objects when data is empty for post-mortem diagnosis."],"tags":["together","upstream-response","image-generation","transient","retry"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}