{"record":{"id":"e6ac66d46230f6c2","repo":"HeyPuter/puter","slug":"bad-request-e6ac66","errorCode":"bad_request","errorMessage":"`prompt` must be a non-empty string","messagePattern":"`prompt` must be a non-empty string","errorType":"validation","errorClass":"HttpError","httpStatus":400,"severity":"warning","filePath":"src/backend/drivers/ai-image/providers/together/TogetherImageProvider.ts","lineNumber":86,"sourceCode":"    }\n\n    getDefaultModel(): string {\n        return DEFAULT_MODEL;\n    }\n\n    async generate(params: IGenerateParams): Promise<string> {\n        const { prompt, test_mode } = params;\n        let { model, ratio, quality } = params;\n        const options = params as TogetherGenerateParams;\n\n        const selectedModel = this.#getModel(model);\n\n        if (test_mode) {\n            return 'https://puter-sample-data.puter.site/image_example.png';\n        }\n\n        if (typeof prompt !== 'string' || prompt.trim().length === 0) {\n            throw new HttpError(400, '`prompt` must be a non-empty string', {\n                legacyCode: 'bad_request',\n            });\n        }\n\n        // Canonical `input_images` → Together's native fields. Together accepts\n        // a single input image: a URL goes to `image_url`, base64/data-URI to\n        // `image_base64` (via the existing `input_image` alias).\n        const singleInput = resolveSingleInputImage(params, 'Together AI');\n        if (singleInput) {\n            if (isHttpUrl(singleInput)) {\n                options.image_url ??= singleInput;\n            } else {\n                options.input_image ??= singleInput;\n            }\n        }\n\n        ratio = ratio || TOGETHER_DEFAULT_RATIO;\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/drivers/ai-image/providers/together/TogetherImageProvider.ts#L68-L104","documentation":"The Together AI image provider rejects calls where the prompt parameter is not a non-empty string. This check (line 85) runs after the test_mode short-circuit, so it applies to all real generation requests. The validation ensures the upstream Together API receives a usable text prompt.","triggerScenarios":"Calling generate() with prompt set to undefined, null, an empty string, a whitespace-only string, or a non-string type (number, object). This can happen if the caller passes a falsy prompt or the prompt field is accidentally omitted from the params object.","commonSituations":"Calling the image generation API with an empty or undefined prompt variable; form submission where the prompt field was left blank; programmatic calls where the prompt is conditionally set but the condition evaluated to a falsy value.","solutions":["Ensure the prompt parameter is a non-empty, non-whitespace string before calling generate().","Validate user input on the client side and show an error message before making the API call.","Use a default prompt or reject the request early if the prompt is missing."],"exampleFix":"// before\nconst result = await provider.generate({ prompt: userPrompt }); // userPrompt may be ''\n\n// after\nif (!userPrompt || typeof userPrompt !== 'string' || !userPrompt.trim()) {\n  throw new Error('Prompt is required');\n}\nconst result = await provider.generate({ prompt: userPrompt.trim() });","handlingStrategy":"validation","validationCode":"function validatePrompt(prompt: unknown): string {\n  if (typeof prompt !== 'string' || prompt.trim().length === 0) {\n    throw new Error('prompt must be a non-empty string');\n  }\n  return prompt.trim();\n}\n// Use before calling generate:\nconst cleanPrompt = validatePrompt(params.prompt);","typeGuard":"function isValidPrompt(value: unknown): value is string {\n  return typeof value === 'string' && value.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always trim and check the prompt on the client side before making the API call.","Disable submit buttons in the UI when the prompt field is empty.","Pass test_mode: true during development to skip upstream costs while testing."],"tags":["together","image-generation","input-validation","prompt"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}