codex-team/editor.js · error · Error

Block with id "${id}" not found

Error message

Block with id "${id}" not found

What it means

editor.blocks.update(id, data, tunes) looks the block up by id via BlockManager.getBlockById; if no block with that id exists (removed, stale id from an earlier save, typo) it throws with the offending id.

Source

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

  public insertNewBlock(): void {
    _.log('Method blocks.insertNewBlock() is deprecated and it will be removed in the next major release. ' +
      'Use blocks.insert() instead.', 'warn');
    this.insert();
  }

  /**
   * Updates block data by id
   *
   * @param id - id of the block to update
   * @param data - (optional) the new data
   * @param tunes - (optional) tune data
   */
  public update = async (id: string, data?: Partial<BlockToolData>, tunes?: {[name: string]: BlockTuneData}): Promise<BlockAPIInterface> => {
    const { BlockManager } = this.Editor;
    const block = BlockManager.getBlockById(id);

    if (block === undefined) {
      throw new Error(`Block with id "${id}" not found`);
    }

    const updatedBlock = await BlockManager.update(block, data, tunes);

    // we cast to any because our BlockAPI has no "new" signature
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return new (BlockAPI as any)(updatedBlock);
  };

  /**
   * Converts block to another type. Both blocks should provide the conversionConfig.
   *
   * @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> => {

View on GitHub (pinned to 5f45dabbe5)

Solutions

  1. Re-fetch fresh ids after any render/structural change before calling update
  2. Check existence first: editor.blocks.getById(id) and skip if null
  3. Wrap in try/catch and refetch the block list on failure

Example fix

// before
await editor.blocks.update(staleId, { text: 'hi' });
// after
const block = editor.blocks.getById(staleId);
if (block) {
  await editor.blocks.update(staleId, { text: 'hi' });
}
Defensive patterns

Strategy: type-guard

Validate before calling

const block = editor.blocks.getById(id); if (!block) throw new Error(`stale id ${id}`); await editor.blocks.update(id, data);

Type guard

const blockExists = (editor: EditorJS, id: string): boolean => editor.blocks.getById(id) !== null;

Try / catch

try { await editor.blocks.update(id, data); } catch (e) { if (e instanceof Error && e.message.includes('not found')) { /* refetch ids and retry once */ } throw e; }

Prevention

When it happens

Trigger: Calling blocks.update() with an id from an old saved document after re-render; using an id captured before the block was deleted; passing a block id from a different editor instance.

Common situations: Async flows that hold a BlockAPI id across a render() or clear() that rebuilt blocks; collaborating/multi-user editing where another user removed the block.

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/f19d00c3a0c566c5. Report an issue: GitHub.