can1357/oh-my-pi · error · Error

Unsupported image encoding: ${encoding}

Error message

Unsupported image encoding: ${encoding}

What it means

Embedded DOCX images expose a read(encoding) method that only supports "base64". Any other encoding string is rejected with this error before the image bytes are converted. The mammoth conversion pipeline calls read("base64") internally, so this only fires when custom image conversion code passes a different encoding.

Source

Thrown at packages/utils/src/docx/converter.ts:393

	const memberPath = relationshipPath(relationship.target);
	const bytes = context.entries.get(memberPath);
	if (!bytes) {
		context.messages.push({ type: "warning", message: `Could not find image ${memberPath}` });
		return "";
	}
	const documentProperties = descendants(element, "docPr")[0];
	const altText = attribute(documentProperties, "descr") ?? attribute(documentProperties, "title") ?? "";
	const extension = path.posix.extname(memberPath).toLowerCase();
	const contentType =
		context.contentTypes.get(memberPath) ??
		context.contentTypes.get(extension) ??
		IMAGE_CONTENT_TYPE_BY_EXTENSION[extension.slice(1)] ??
		"application/octet-stream";
	const image: DocxImage = {
		contentType,
		altText,
		async read(encoding: "base64"): Promise<string> {
			if (encoding !== "base64") throw new Error(`Unsupported image encoding: ${encoding}`);
			return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
		},
	};
	const converted = await context.convertImage.convert(image);
	const attributes = Object.entries(converted)
		.filter((entry): entry is [string, string] => typeof entry[1] === "string")
		.sort(([left], [right]) => left.localeCompare(right))
		.map(([name, value]) => `${name}="${escapeAttribute(value)}"`)
		.join(" ");
	return attributes ? `<img ${attributes} />` : "<img />";
}

function renderFootnoteReference(element: XmlElement, context: ConversionContext): string {
	const id = attribute(element, "w:id");
	if (!id || !context.footnotes.has(id)) return "";
	let ordinal = context.footnoteOrdinals.get(id);
	if (ordinal === undefined) {
		ordinal = context.usedFootnotes.length + 1;

View on GitHub (pinned to 9690622007)

Solutions

  1. Call read("base64") — it is the only supported encoding; decode the returned base64 yourself if you need raw bytes.
  2. For raw bytes, use Buffer.from(await image.read("base64"), "base64") instead of asking read() for another encoding.
  3. If you control the custom convertImage transform, hard-code the encoding argument to "base64".

Example fix

// before
const data = await image.read("utf8"); // throws

// after
const b64 = await image.read("base64");
const bytes = Buffer.from(b64, "base64");
Defensive patterns

Strategy: type-guard

Type guard

function isBase64Encoding(encoding: string): encoding is "base64" {
  return encoding === "base64";
}
if (!isBase64Encoding(encoding)) throw new Error("only base64 is supported");

Try / catch

let data: string;
try {
  data = await image.read(encoding);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Unsupported image encoding")) {
    data = await image.read("base64");
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the DocxImage.read() method with an encoding other than "base64" (e.g. "utf8", "hex", "binary"), or supplying a custom convertImage handler that invokes image.read() with a non-base64 encoding argument.

Common situations: Writing a custom mammoth convertImage transform that defaults to "utf8"; assuming read() accepts Buffer encodings like "hex" for hashing; copying mammoth examples that use "data-uri" style encodings.

Related errors


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