codex-team/editor.js · error · Error

Block Tool with type "${newType}" not found

Error message

Block Tool with type "${newType}" not found

What it means

During blocks.convert(id, newType) the target tool name is looked up in Tools.blockTools; an unregistered tool name throws this error. Only tools registered in editor config (or internal tools) can be conversion targets.

Source

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

   *
   * @param id - id of the existing block to convert. Should provide 'conversionConfig.export' method
   * @param newType - new block type. Should provide 'conversionConfig.import' method
   * @param dataOverrides - optional data overrides for the new block
   * @throws Error if conversion is not possible
   */
  private convert = async (id: string, newType: string, dataOverrides?: BlockToolData): Promise<BlockAPIInterface> => {
    const { BlockManager, Tools } = this.Editor;
    const blockToConvert = BlockManager.getBlockById(id);

    if (!blockToConvert) {
      throw new Error(`Block with id "${id}" not found`);
    }

    const originalBlockTool = Tools.blockTools.get(blockToConvert.name);
    const targetBlockTool = Tools.blockTools.get(newType);

    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"`);
    }
  };

View on GitHub (pinned to 5f45dabbe5)

Solutions

  1. Register the target tool in the Editor.js tools config before calling convert
  2. Verify the exact tool name via Object.keys of your tools config / editor.tools
  3. Use the canonical internal name (e.g. 'paragraph', 'header') matching your config key

Example fix

// before
EditorJS.create({ tools: { paragraph: Paragraph }, ... });
editor.blocks.convert(id, 'header');
// after
EditorJS.create({ tools: { paragraph: Paragraph, header: Header }, ... });
editor.blocks.convert(id, 'header');
Defensive patterns

Strategy: validation

Validate before calling

const known = new Set(Object.keys(toolsConfig)); if (!known.has(newType)) throw new Error(`tool ${newType} not registered`); await editor.blocks.convert(id, newType);

Type guard

const isRegisteredTool = (name: string, cfg: Record<string, unknown>): name is string => name in cfg;

Try / catch

try { await editor.blocks.convert(id, newType); } catch (e) { if (e instanceof Error && e.message.includes('Tool with type')) { /* register tool then retry */ } throw e; }

Prevention

When it happens

Trigger: Calling editor.blocks.convert(id, 'myTool') when 'myTool' was never passed in the tools config; misspelling a tool name; using a tool name that is an inline or block tune rather than a block tool.

Common situations: Copying example code that converts to a tool not installed; tool name casing mismatch ('Header' vs 'header'); tool registered lazily after the convert call.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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