{"record":{"id":"ca7cba9f337cb6ed","repo":"antlr/antlr4","slug":"insert-op-within-boundaries-of-previous","errorCode":null,"errorMessage":"insert op {} within boundaries of previous {}","messagePattern":"insert op (.+?) within boundaries of previous (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"runtime/Python3/src/antlr4/TokenStreamRewriter.py","lineNumber":189,"sourceCode":"            if any((iop is None, not isinstance(iop, TokenStreamRewriter.InsertBeforeOp))):\n                continue\n            prevInserts = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.InsertBeforeOp)]\n            for prev_index, prevIop in enumerate(prevInserts):\n                if prevIop.index == iop.index and type(prevIop) is TokenStreamRewriter.InsertBeforeOp:\n                    iop.text += prevIop.text\n                    rewrites[prev_index] = None\n                elif prevIop.index == iop.index and type(prevIop) is TokenStreamRewriter.InsertAfterOp:\n                    iop.text = prevIop.text + iop.text\n                    rewrites[prev_index] = None\n            # look for replaces where iop.index is in range; error\n            prevReplaces = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.ReplaceOp)]\n            for rop in prevReplaces:\n                if iop.index == rop.index:\n                    rop.text = iop.text + rop.text\n                    rewrites[i] = None\n                    continue\n                if all((iop.index >= rop.index, iop.index <= rop.last_index)):\n                    raise ValueError(\"insert op {} within boundaries of previous {}\".format(iop, rop))\n\n        reduced = {}\n        for i, op in enumerate(rewrites):\n            if op is None: continue\n            if reduced.get(op.index): raise ValueError('should be only one op per index')\n            reduced[op.index] = op\n\n        return reduced\n\n    class RewriteOperation(object):\n        __slots__ = ('tokens', 'index', 'text', 'instructionIndex')\n\n        def __init__(self, tokens, index, text=\"\"):\n            \"\"\"\n            :type tokens: CommonTokenStream\n            :param tokens:\n            :param index:\n            :param text:","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Python3/src/antlr4/TokenStreamRewriter.py#L171-L207","documentation":"In the reduction pass, an InsertBeforeOp/InsertAfterOp whose index falls strictly inside a previous ReplaceOp's range (not exactly at its start index, which is merged as prepend) raises this ValueError. Inserting text inside a region that is about to be replaced is meaningless — the replacement would erase it — so ANTLR refuses rather than silently dropping the insert.","triggerScenarios":"rewriter.insertAfter(3, 'x') or insertBefore(3, 'x') after rewriter.replace(2, 5, 'y') in the same program: 3 is within 2..5 and != 2, so the insert is rejected.","commonSituations":"Automated refactoring tools that emit inserts and replaces from independent passes; listeners that insert tokens near operators while another visitor replaces whole expressions.","solutions":["Move the insert outside the replaced range, or fold the inserted text into the replacement text itself.","If the insert belongs at the start of the replaced span, use index == rop.index (that case is merged as a prepend, not an error).","Put independent insert/replace passes in different program names and render them in separate getText() calls."],"exampleFix":"// before\nrewriter.replace(2, 5, 'new')\nrewriter.insertBefore(3, 'x')  // 3 inside 2..5 -> ValueError\n\n// after\nrewriter.replace(2, 5, 'xnew')  # text folded into the replacement","handlingStrategy":"validation","validationCode":"def insert_safe(replaces, index):\n    # replaces: list of (start, end) already submitted to this program\n    return all(not (start < index <= end) for start, end in replaces)","typeGuard":null,"tryCatchPattern":"try:\n    rewriter.insertBefore(i, text)\nexcept ValueError as e:\n    if 'within boundaries' in str(e):\n        # fold text into the covering replacement instead\n        pass\n    else:\n        raise","preventionTips":["Track submitted replace ranges per program and reject/redirect inserts inside them","Fold inserted text into the replacement string when the target index is inside a replaced span","Keep insert and replace phases in separate programs"],"tags":["antlr4","python","token-stream-rewriter","insert-after-replace","validation"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}