can1357/oh-my-pi · error · Error

Conversion failed: ${details}

Error message

Conversion failed:
${details}

What it means

Markit.convert tries every registered converter that accepts the stream; if at least one candidate ran but all failed, it aggregates their errors and throws a single 'Conversion failed:' error listing '<converter>: <message>' per line. It signals the format was recognized but every applicable converter rejected or crashed on the content.

Source

Thrown at packages/coding-agent/src/markit/registry.ts:55

			filename: path.basename(filePath),
			...extra,
		};
		return this.convert(buffer, streamInfo);
	}

	async convert(input: Buffer, streamInfo: StreamInfo): Promise<ConversionResult> {
		const errors: { converter: string; error: Error }[] = [];
		for (const converter of this.#converters) {
			if (!converter.accepts(streamInfo)) continue;
			try {
				return await converter.convert(input, streamInfo, this.#options);
			} catch (err) {
				errors.push({ converter: converter.name, error: err instanceof Error ? err : new Error(String(err)) });
			}
		}
		if (errors.length > 0) {
			const details = errors.map(e => `  ${e.converter}: ${e.error.message}`).join("\n");
			throw new Error(`Conversion failed:\n${details}`);
		}
		throw new Error(`Unsupported format: ${streamInfo.extension || streamInfo.mimetype || "unknown"}`);
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the per-converter messages after 'Conversion failed:' — they name the root cause for each converter.
  2. Fix the underlying document (repair, decrypt, or re-export it) based on those messages.
  3. Verify the file is complete and non-empty; re-download or re-export.
  4. If no converter matched at all, the registry instead reports 'Unsupported format' — check extension/mimetype routing.

Example fix

// caller-side handling
try {
  const result = await markit.convertFile("protected.pdf");
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Conversion failed:")) {
    // inspect per-converter detail lines, e.g. decrypt the PDF first
  }
  throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

import * as fs from "node:fs";
function fileLooksReadable(path: string): boolean {
  const st = fs.statSync(path);
  return st.isFile() && st.size > 0;
}

Type guard

function isConversionFailedError(err: unknown): err is Error & { message: string } {
  return err instanceof Error && err.message.startsWith("Conversion failed:\n");
}

Try / catch

try {
  const result = await markit.convertFile("doc.pdf");
} catch (err) {
  if (isConversionFailedError(err)) {
    const perConverter = err.message.split("\n").slice(1); // ['  Pdf: ...', ...]
    console.error(perConverter);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling convert/convertFile on a stream whose extension/mimetype matches one or more converters, but each converter's convert() threw (corrupt document, parser exception, encrypted/DRM file, password-protected PDF, etc.).

Common situations: Encrypted or password-protected PDF; malformed docx/epub produced by buggy generators; empty or truncated file passed with a recognized extension; parser library incompatibility.

Related errors


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