{"record":{"id":"b03f7677580db928","repo":"siyuan-note/siyuan","slug":"image-prompt-is-required","errorCode":null,"errorMessage":"image prompt is required","messagePattern":"image prompt is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/openai.go","lineNumber":735,"sourceCode":"\t\treturn \"\", \"\", errors.New(\"generated image is invalid\")\n\t}\n\treturn mimeType, extension, nil\n}\n\nfunc NewOpenAIImageAdapter(apiKey, apiBaseURL, model string, timeout int) *OpenAIImageAdapter {\n\tif timeout < 1 {\n\t\ttimeout = 30\n\t}\n\treturn &OpenAIImageAdapter{\n\t\tclient:  NewOpenAIClientWithModel(apiKey, apiBaseURL, model),\n\t\tmodel:   model,\n\t\ttimeout: time.Duration(timeout) * time.Second,\n\t}\n}\n\nfunc (adapter *OpenAIImageAdapter) Generate(ctx context.Context, request GenerateImageRequest) (GeneratedImage, error) {\n\tif strings.TrimSpace(request.Prompt) == \"\" {\n\t\treturn GeneratedImage{}, errors.New(\"image prompt is required\")\n\t}\n\timageRequest := openai.ImageRequest{\n\t\tPrompt:  request.Prompt,\n\t\tModel:   adapter.model,\n\t\tN:       1,\n\t\tSize:    request.Size,\n\t\tQuality: request.Quality,\n\t}\n\tif strings.HasPrefix(strings.ToLower(adapter.model), \"dall-e\") {\n\t\timageRequest.ResponseFormat = openai.CreateImageResponseFormatB64JSON\n\t\tif imageRequest.Quality == \"auto\" {\n\t\t\timageRequest.Quality = \"\"\n\t\t}\n\t} else {\n\t\timageRequest.OutputFormat = request.OutputFormat\n\t}\n\trequestCtx, cancel := context.WithTimeout(ctx, adapter.timeout)\n\tdefer cancel()","sourceCodeStart":717,"sourceCodeEnd":753,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/openai.go#L717-L753","documentation":"Thrown by OpenAIImageAdapter.Generate (kernel/util/openai.go:735) when strings.TrimSpace(request.Prompt) is empty. It is the input-contract guard at the very top of Generate and exists because the OpenAI image API rejects empty prompts with a less obvious upstream error; SiYuan fails fast with a clear message instead.","triggerScenarios":"Calling adapter.Generate with a GenerateImageRequest whose Prompt is \"\", whitespace-only, or accidentally unset (zero value of the struct).","commonSituations":"Frontend sends the request before the user typed a prompt; an agent/automation pipeline forwards an empty prompt field; a serialization bug drops the prompt key; default struct zero value used unintentionally.","solutions":["Validate the prompt at the calling layer (HTTP handler, agent runtime) before invoking Generate, returning a user-facing message.","Trim and reject prompt == '' on the UI side so the call is never made.","If an automation pipeline triggers it, audit the prompt construction step."],"exampleFix":"// before\nimg, err := adapter.Generate(ctx, GenerateImageRequest{Prompt: req.Prompt, Size: req.Size})\n\n// after\nprompt := strings.TrimSpace(req.Prompt)\nif prompt == \"\" {\n    return nil, errors.New(\"prompt is required\")\n}\nimg, err := adapter.Generate(ctx, GenerateImageRequest{Prompt: prompt, Size: req.Size})","handlingStrategy":"validation","validationCode":"prompt := strings.TrimSpace(request.Prompt)\nif prompt == \"\" {\n    return errors.New(\"image prompt is required\")\n}\nrequest.Prompt = prompt","typeGuard":null,"tryCatchPattern":"img, err := adapter.Generate(ctx, request)\nif err != nil && err.Error() == \"image prompt is required\" {\n    // surface to user as a form-validation issue, not a system error\n    return promptRequiredError{}\n}\nif err != nil { return err }","preventionTips":["Trim and reject empty prompts in the HTTP/agent layer before calling Generate.","Disable submit until a non-empty prompt is entered in the UI.","In automation pipelines, assert prompt construction produces non-empty output before dispatch."],"tags":["openai","image-generation","input-validation","go"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}