siyuan-note/siyuan · error

image model returned neither base64 data nor URL

Error message

image model returned neither base64 data nor URL

What it means

Thrown by OpenAIImageAdapter.Generate (kernel/util/openai.go:768) when response.Data has at least one element but its first element has neither B64JSON nor a URL. SiYuan requires exactly one of these transport modes; absence of both means the provider's response item schema does not match the openai-go client's expectations.

Source

Thrown at kernel/util/openai.go:768

		imageRequest.OutputFormat = request.OutputFormat
	}
	requestCtx, cancel := context.WithTimeout(ctx, adapter.timeout)
	defer cancel()
	response, err := adapter.client.CreateImage(requestCtx, imageRequest)
	if err != nil {
		return GeneratedImage{}, err
	}
	if len(response.Data) == 0 {
		return GeneratedImage{}, errors.New("image model returned no image")
	}
	result := response.Data[0]
	var data []byte
	if result.B64JSON != "" {
		data, err = base64.StdEncoding.DecodeString(result.B64JSON)
	} else if result.URL != "" {
		data, err = downloadGeneratedImage(requestCtx, result.URL)
	} else {
		err = errors.New("image model returned neither base64 data nor URL")
	}
	if err != nil {
		return GeneratedImage{}, err
	}
	mimeType, extension, err := ValidateGeneratedImage(data)
	if err != nil {
		return GeneratedImage{}, err
	}
	return GeneratedImage{Data: data, MIMEType: mimeType, Extension: extension, RevisedPrompt: result.RevisedPrompt}, nil
}

func downloadGeneratedImage(ctx context.Context, rawURL string) ([]byte, error) {
	parsed, err := url.Parse(rawURL)
	if err != nil || parsed.Scheme != "https" || parsed.Host == "" {
		return nil, errors.New("generated image URL must use HTTPS")
	}
	if err = CheckHostSSRF(parsed.Hostname()); err != nil {
		return nil, err

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Update the openai-go client to a version matching the provider's current image API schema.
  2. Dump response.Data[0] (marshalled JSON) to see which fields the provider actually populates.
  3. If the provider uses a different field name, switch to a compatible adapter or normalize the response.
  4. Retry once in case the item was a transient stub.

Example fix

// before
if result.B64JSON != "" {
    data, err = base64.StdEncoding.DecodeString(result.B64JSON)
} else if result.URL != "" {
    data, err = downloadGeneratedImage(requestCtx, result.URL)
} else {
    err = errors.New("image model returned neither base64 data nor URL")
}

// after (surface provider payload for diagnosis)
if result.B64JSON != "" {
    data, err = base64.StdEncoding.DecodeString(result.B64JSON)
} else if result.URL != "" {
    data, err = downloadGeneratedImage(requestCtx, result.URL)
} else {
    raw, _ := json.Marshal(result)
    err = fmt.Errorf("image model returned neither base64 data nor URL; item=%s", raw)
}
Defensive patterns

Strategy: validation

Validate before calling

// Inspect the item fields before dispatching to decode/download
result := response.Data[0]
if result.B64JSON == "" && result.URL == "" {
    raw, _ := json.Marshal(result)
    return fmt.Errorf("provider item has no b64/URL; item=%s", raw)
}

Try / catch

if result.B64JSON != "" {
    data, err = base64.StdEncoding.DecodeString(result.B64JSON)
} else if result.URL != "" {
    data, err = downloadGeneratedImage(ctx, result.URL)
} else {
    // schema drift: dump the item, retry once, then escalate
    raw, _ := json.Marshal(result)
    logging.LogErrorf("unexpected image item shape: %s", raw)
    err = fmt.Errorf("image model returned neither base64 data nor URL")
}

Prevention

When it happens

Trigger: Provider returns a data item with only a revised_prompt field and no payload; provider uses a non-standard field name (e.g. b64_json vs b64Json casing mismatch); openai-go client version out of sync with provider schema.

Common situations: OpenAI-compatible third-party endpoint with a different response envelope; client/server version mismatch after a provider API update; content-policy rejection that returns a stub item with neither field.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/b012a3235e75a1c8. Report an issue: GitHub.