{"record":{"id":"a36227152637e60d","repo":"siyuan-note/siyuan","slug":"image-model-returned-no-image","errorCode":null,"errorMessage":"image model returned no image","messagePattern":"image model returned no image","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/openai.go","lineNumber":759,"sourceCode":"\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()\n\tresponse, err := adapter.client.CreateImage(requestCtx, imageRequest)\n\tif err != nil {\n\t\treturn GeneratedImage{}, err\n\t}\n\tif len(response.Data) == 0 {\n\t\treturn GeneratedImage{}, errors.New(\"image model returned no image\")\n\t}\n\tresult := response.Data[0]\n\tvar data []byte\n\tif result.B64JSON != \"\" {\n\t\tdata, err = base64.StdEncoding.DecodeString(result.B64JSON)\n\t} else if result.URL != \"\" {\n\t\tdata, err = downloadGeneratedImage(requestCtx, result.URL)\n\t} else {\n\t\terr = errors.New(\"image model returned neither base64 data nor URL\")\n\t}\n\tif err != nil {\n\t\treturn GeneratedImage{}, err\n\t}\n\tmimeType, extension, err := ValidateGeneratedImage(data)\n\tif err != nil {\n\t\treturn GeneratedImage{}, err\n\t}\n\treturn GeneratedImage{Data: data, MIMEType: mimeType, Extension: extension, RevisedPrompt: result.RevisedPrompt}, nil","sourceCodeStart":741,"sourceCodeEnd":777,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/openai.go#L741-L777","documentation":"Thrown by OpenAIImageAdapter.Generate (kernel/util/openai.go:759) when adapter.client.CreateImage succeeded (no Go error) but response.Data is empty. SiYuan treats this as a provider contract violation: a successful HTTP call must yield at least one image element.","triggerScenarios":"The image API returns HTTP 200 with an empty data array. Common with content-filter rejections that surface as empty rather than as errors, or with provider/schema drift where the response shape changed.","commonSituations":"The prompt tripped the provider's content filter (returned empty instead of an error); quota/billing edge case; provider changed its response envelope; an OpenAI-compatible shim that does not populate Data on certain model states.","solutions":["Retry once with the same or a slightly reworded prompt — content-filter empties are often prompt-specific.","Inspect the raw HTTP response from CreateImage (enable client debug logging) to confirm the data array really is empty and not just misparsed.","Update the openai-go client version in case of schema drift.","Sanitize/soften the prompt to avoid the provider's safety filter."],"exampleFix":"// before\nresponse, err := adapter.client.CreateImage(requestCtx, imageRequest)\nif err != nil { return GeneratedImage{}, err }\nif len(response.Data) == 0 {\n    return GeneratedImage{}, errors.New(\"image model returned no image\")\n}\n\n// after (one retry, then descriptive error)\nresponse, err := adapter.client.CreateImage(requestCtx, imageRequest)\nif err != nil { return GeneratedImage{}, err }\nif len(response.Data) == 0 {\n    logging.LogWarnf(\"model %s returned empty data; retrying\", adapter.model)\n    response, err = adapter.client.CreateImage(requestCtx, imageRequest)\n    if err != nil { return GeneratedImage{}, err }\n    if len(response.Data) == 0 {\n        return GeneratedImage{}, fmt.Errorf(\"model %s returned no image (possible content filter)\", adapter.model)\n    }\n}","handlingStrategy":"retry","validationCode":"// No purely client-side check; closest is to retry CreateImage once before treating as failure\n// (Validation belongs around the call site, see tryCatchPattern.)","typeGuard":null,"tryCatchPattern":"response, err := adapter.client.CreateImage(ctx, req)\nif err != nil { return GeneratedImage{}, err }\nif len(response.Data) == 0 {\n    logging.LogWarnf(\"empty data array; retrying once\")\n    response, err = adapter.client.CreateImage(ctx, req)\n    if err != nil { return GeneratedImage{}, err }\n    if len(response.Data) == 0 {\n        return GeneratedImage{}, fmt.Errorf(\"model %s returned no image (possible content filter)\", adapter.model)\n    }\n}","preventionTips":["Treat 'no image but 200 OK' as a likely content-filter rejection and reword the prompt.","Keep the openai-go client up to date to track provider schema changes.","Log the full response when Data is empty so root cause is captured."],"tags":["openai","image-generation","provider","retry","go"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}