{"record":{"id":"362ebd9688fa9778","repo":"codex-team/editor.js","slug":"incorrect-index","errorCode":null,"errorMessage":"Incorrect index","messagePattern":"Incorrect index","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/components/blocks.ts","lineNumber":232,"sourceCode":"      const nextBlock = this.blocks[index + 1];\n\n      if (nextBlock) {\n        this.insertToDOM(block, 'beforebegin', nextBlock);\n      } else {\n        this.insertToDOM(block);\n      }\n    }\n  }\n\n  /**\n   * Replaces block under passed index with passed block\n   *\n   * @param index - index of existed block\n   * @param block - new block\n   */\n  public replace(index: number, block: Block): void {\n    if (this.blocks[index] === undefined) {\n      throw Error('Incorrect index');\n    }\n\n    const prevBlock = this.blocks[index];\n\n    prevBlock.holder.replaceWith(block.holder);\n\n    this.blocks[index] = block;\n  }\n\n  /**\n   * Inserts several blocks at once\n   *\n   * @param blocks - blocks to insert\n   * @param index - index to insert blocks at\n   */\n  public insertMany(blocks: Block[], index: number ): void {\n    const fragment = new DocumentFragment();\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/codex-team/editor.js/blob/5f45dabbe5690b7033b2f9047d3985add5045fdd/src/components/blocks.ts#L214-L250","documentation":"BlockCollection.replace(index, block) swaps a block in the internal array; if blocks[index] is undefined (index past the end or negative) it throws 'Incorrect index'. Reached via internal flows like beautifyShortcut and isNodeEmpty handling.","triggerScenarios":"An internal operation calling replace with an index no longer valid because blocks were removed concurrently (undo/redo race, rapid deletion), or an out-of-range index computed from a stale count.","commonSituations":"Race conditions between keyboard shortcuts (beautify/enter handling) and asynchronous block removal; bugs in custom code reaching into BlockManager.replace with stale indices.","solutions":["Refresh the index immediately before calling replace instead of caching it","Ensure index < blocks.length before replace","Serialize structural block operations so removals can't interleave"],"exampleFix":"// before\nblockCollection.replace(staleIndex, newBlock);\n// after\nif (blockCollection.blocks[staleIndex] !== undefined) {\n  blockCollection.replace(staleIndex, newBlock);\n}","handlingStrategy":"validation","validationCode":"if (blockCollection.blocks[index] !== undefined) { blockCollection.replace(index, newBlock); }","typeGuard":"const isValidBlockIndex = (blocks: Block[], i: number): boolean => Number.isInteger(i) && i >= 0 && i < blocks.length;","tryCatchPattern":"try { blockCollection.replace(index, block); } catch (e) { if (e instanceof Error && e.message === 'Incorrect index') { /* recompute index and retry */ } throw e; }","preventionTips":["Recompute indices right before structural ops","Serialize block mutations to avoid races"],"tags":["replace","index","bounds-check","race-condition"],"backgroundTag":"index-out-of-bounds","analyzedSha":"5f45dabbe5690b7033b2f9047d3985add5045fdd","analyzedAt":"2026-08-27T22:50:23.124Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}