{"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":882,"sourceCode":"\t\ttimeout = 30\n\t}\n\tclient := NewOpenAIClientWithModel(apiKey, apiBaseURL, model, headers...)\n\tif isMiniMaxImageEndpoint(apiBaseURL) {\n\t\tconfig := openai.DefaultConfig(apiKey)\n\t\tconfig.BaseURL = apiBaseURL\n\t\tconfig.HTTPClient = &miniMaxImageTransport{base: newAIProviderHTTPClient(apiBaseURL, headers...)}\n\t\tclient = openai.NewClientWithConfig(config)\n\t}\n\treturn &OpenAIImageAdapter{\n\t\tclient:  client,\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":864,"sourceCodeEnd":900,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/openai.go#L864-L900","documentation":"SiYuan's OpenAI image adapter refuses to call the image API when the request prompt is empty or whitespace-only. The prompt is the one required input for text-to-image models (DALL·E etc.), so the adapter fails fast with a clear message instead of sending a request the provider would reject. This is a client-side guard in OpenAIImageAdapter.Generate.","triggerScenarios":"Calling Generate (directly or via the kernel AI image endpoint) with GenerateImageRequest.Prompt set to \"\", \"   \", or left unset after trimming.","commonSituations":"Frontend sends an empty prompt field; a pipeline passes a variable that was never populated; user submits the image dialog without typing a prompt; upstream text step produced an empty string that was passed through unchecked.","solutions":["Ensure request.Prompt is set to a non-empty, non-whitespace string before calling Generate","In the caller, check strings.TrimSpace(prompt) != \"\" and return a user-facing 'prompt required' message instead","Fix the UI/client to disable the generate action until a prompt is entered"],"exampleFix":"// before\ngenerated, err := adapter.Generate(ctx, GenerateImageRequest{Size: \"1024x1024\"})\n// after\nprompt := strings.TrimSpace(userPrompt)\nif prompt == \"\" {\n    return errors.New(\"please enter an image prompt\")\n}\ngenerated, err := adapter.Generate(ctx, GenerateImageRequest{Prompt: prompt, Size: \"1024x1024\"})","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(prompt) == \"\" {\n    return errors.New(\"image prompt is required\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always trim and check the prompt before invoking image generation","Disable the UI generate button until a prompt is entered","Validate required fields at the API boundary before reaching the adapter"],"tags":["openai","image-generation","validation"],"backgroundTag":"empty-required-field","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}