can1357/oh-my-pi · error

Image data is empty.

Error message

Image data is empty.

What it means

For a data: URL whose mime type parsed correctly, the base64 payload portion must still be non-empty; normalizeDataUrl returning empty data means the URL contained a header but no (or only empty) base64 payload. The tool throws to avoid sending an inline image with zero bytes, which upstream providers reject. It is a client-side validation of malformed inline image input.

Source

Thrown at packages/coding-agent/src/tools/image-gen.ts:389

	return model.includes("/") ? model : `google/${model}`;
}

function toDataUrl(image: InlineImageData): string {
	return `data:${image.mimeType};base64,${image.data}`;
}

async function loadImageFromUrl(
	imageUrl: string,
	fetchImpl: FetchImpl,
	signal?: AbortSignal,
): Promise<InlineImageData> {
	if (imageUrl.startsWith("data:")) {
		const normalized = normalizeDataUrl(imageUrl.trim());
		if (!normalized.mimeType) {
			throw new Error("mime_type is required when providing raw base64 data.");
		}
		if (!normalized.data) {
			throw new Error("Image data is empty.");
		}
		return { data: normalized.data, mimeType: normalized.mimeType };
	}

	const response = await fetchImpl(imageUrl, { signal });
	if (!response.ok) {
		const rawText = await response.text();
		throw new Error(`Image download failed (${response.status}): ${rawText}`);
	}
	const contentType = response.headers.get("content-type")?.split(";")[0];
	if (!contentType?.startsWith("image/")) {
		throw new Error(`Unsupported image type from URL: ${imageUrl}`);
	}
	const buffer = await response.bytes();
	return { data: buffer.toBase64(), mimeType: contentType };
}

function collectOpenRouterResponseText(message: OpenRouterMessage | undefined): string | undefined {

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the data URL actually contains base64 data after the comma
  2. Re-generate the base64 encoding from the source file (e.g. `base64 -w0 image.png` or `Bun.file(path).base64()`)
  3. Fall back to passing a file path instead of an inline data URL
  4. Log the data-URL length before the call to catch empty payloads early

Example fix

// before
const url = `data:image/png;base64,${b64}`; // b64 was ""
// after
const b64 = Bun.file("logo.png").base64();
if (!b64) throw new Error("source image is empty");
const url = `data:image/png;base64,${b64}`;
Defensive patterns

Strategy: validation

Validate before calling

function validateDataUrlPayload(url: string): boolean {
	const idx = url.indexOf(",");
	return idx !== -1 && url.length > idx + 1 && /^[A-Za-z0-9+/=\s]+$/.test(url.slice(idx + 1));
}

Try / catch

try {
	await genImage({ image: dataUrl });
} catch (err) {
	if (err instanceof Error && err.message === "Image data is empty.") {
		// re-encode from source and retry once
	}
	throw err;
}

Prevention

When it happens

Trigger: Calling image generation with `data:image/png;base64,` (trailing comma, empty payload) or a data URL whose payload was lost during string construction/interpolation.

Common situations: Template variables that failed to fill in the base64 string; truncation from config limits or copy-paste; encoders producing empty output for empty input buffers.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/1895413614debe3c. Report an issue: GitHub.