codex-team/editor.js · error · Error

Conversion from "${blockToConvert.name}" to "${newType}" is

Error message

Conversion from "${blockToConvert.name}" to "${newType}" is not possible. ${unsupportedBlockTypes} tool(s) should provide a "conversionConfig"

What it means

Block conversion uses each tool's conversionConfig (export/import). If the source tool lacks `export` or the target tool lacks `import`, the conversion pipeline cannot run and this error names the offending tool(s).

Source

Thrown at src/components/modules/api/blocks.ts:378

    if (!targetBlockTool) {
      throw new Error(`Block Tool with type "${newType}" not found`);
    }

    const originalBlockConvertable = originalBlockTool?.conversionConfig?.export !== undefined;
    const targetBlockConvertable = targetBlockTool.conversionConfig?.import !== undefined;

    if (originalBlockConvertable && targetBlockConvertable) {
      const newBlock = await BlockManager.convert(blockToConvert, newType, dataOverrides);

      return new BlockAPI(newBlock);
    } else {
      const unsupportedBlockTypes = [
        !originalBlockConvertable ? capitalize(blockToConvert.name) : false,
        !targetBlockConvertable ? capitalize(newType) : false,
      ].filter(Boolean).join(' and ');

      throw new Error(`Conversion from "${blockToConvert.name}" to "${newType}" is not possible. ${unsupportedBlockTypes} tool(s) should provide a "conversionConfig"`);
    }
  };


  /**
   * Inserts several Blocks to a specified index
   *
   * @param blocks - blocks data to insert
   * @param index - index to insert the blocks at
   */
  private insertMany = (
    blocks: OutputBlockData[],
    index: number = this.Editor.BlockManager.blocks.length - 1
  ): BlockAPIInterface[] => {
    this.validateIndex(index);

    const blocksToInsert = blocks.map(({ id, type, data }) => {
      return this.Editor.BlockManager.composeBlock({

View on GitHub (pinned to 5f45dabbe5)

Solutions

  1. Add conversionConfig {export, import} to the tool(s) named in the message
  2. Convert to a tool that already supports conversion (e.g. one with a defined conversionConfig)
  3. Skip the conversion in UI when neither side supports it

Example fix

// before
class MyTool {
  static get conversionConfig() { return; }
}
// after
class MyTool {
  static get conversionConfig() {
    return {
      export: (data) => data.text,
      import: (raw) => ({ text: raw }),
    };
  }
}
Defensive patterns

Strategy: validation

Validate before calling

const canConvert = (from: BlockToolConstructable, to: BlockToolConstructable) => Boolean(from.conversionConfig?.export && to.conversionConfig?.import);

Type guard

const supportsConversion = (t: unknown): t is { conversionConfig: { export: unknown; import: unknown } } => Boolean((t as any)?.conversionConfig?.export && (t as any)?.conversionConfig?.import);

Try / catch

try { await editor.blocks.convert(id, newType); } catch (e) { if (e instanceof Error && e.message.includes('conversionConfig')) { /* show unsupported message */ } throw e; }

Prevention

When it happens

Trigger: Calling blocks.convert(id, 'toolX') where either the current block's tool or 'toolX' does not define conversionConfig.export/import; converting from/to the paragraph tool without a custom conversion config where required.

Common situations: Third-party tools that never implemented conversionConfig; assuming every tool is convertible; converting between two custom tools where only one side defines export/import.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of codex-team/editor.js@5f45dabbe5 (2026-08-27). Data as JSON: /api/errors/08e0a30222bb9eac. Report an issue: GitHub.