{"record":{"id":"e183ec4bf550ee5b","repo":"antlr/antlr4","slug":"illegalstate","errorCode":null,"errorMessage":"IllegalState","messagePattern":"IllegalState","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"runtime/Python3/src/antlr4/atn/ATNDeserializer.py","lineNumber":167,"sourceCode":"\n        # edges for rule stop states can be derived, so they aren't serialized\n        for state in atn.states:\n            for i in range(0, len(state.transitions)):\n                t = state.transitions[i]\n                if not isinstance(t, RuleTransition):\n                    continue\n                outermostPrecedenceReturn = -1\n                if atn.ruleToStartState[t.target.ruleIndex].isPrecedenceRule:\n                    if t.precedence == 0:\n                        outermostPrecedenceReturn = t.target.ruleIndex\n                trans = EpsilonTransition(t.followState, outermostPrecedenceReturn)\n                atn.ruleToStopState[t.target.ruleIndex].addTransition(trans)\n\n        for state in atn.states:\n            if isinstance(state, BlockStartState):\n                # we need to know the end state to set its start state\n                if state.endState is None:\n                    raise Exception(\"IllegalState\")\n                # block end states can only be associated to a single block start state\n                if state.endState.startState is not None:\n                    raise Exception(\"IllegalState\")\n                state.endState.startState = state\n\n            if isinstance(state, PlusLoopbackState):\n                for i in range(0, len(state.transitions)):\n                    target = state.transitions[i].target\n                    if isinstance(target, PlusBlockStartState):\n                        target.loopBackState = state\n            elif isinstance(state, StarLoopbackState):\n                for i in range(0, len(state.transitions)):\n                    target = state.transitions[i].target\n                    if isinstance(target, StarLoopEntryState):\n                        target.loopBackState = state\n\n    def readDecisions(self, atn:ATN):\n        ndecisions = self.readInt()","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Python3/src/antlr4/atn/ATNDeserializer.py#L149-L185","documentation":"While linking deserialized states, every BlockStartState must reference a BlockEndState. This check fires when a BlockStartState has endState == None, i.e. the serialized ATN is internally inconsistent. With well-formed ANTLR tool output this never happens; in practice it signals truncated or corrupted serialized ATN data (e.g. a partial copy of a generated file, or a version skew that misaligns the data stream).","triggerScenarios":"ATNDeserializer.deserialize() where a block start state's serialized end-state reference failed to resolve — corrupt data array, truncated serialized string, or deserialization reading garbage after a version mismatch.","commonSituations":"Hand-editing or regex-refactoring generated parser files and breaking the embedded serialized ATN; file transfer/encoding corruption (non-UTF-8 round trip); tool/runtime version mismatch shifting the read cursor.","solutions":["Regenerate the lexer/parser from the grammar with the ANTLR tool matching your runtime version and discard any manually patched generated files.","Verify the generated file was not mangled (line endings, encoding, copy-paste truncation); restore from a clean generation.","Confirm the runtime version equals the tool version (see error 'Could not deserialize ATN with version')."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    parser = MyParser(tokens)\nexcept Exception as e:\n    if 'IllegalState' in str(e):\n        raise RuntimeError('Serialized ATN is corrupt: regenerate generated files with the matching ANTLR tool version')\n    raise","preventionTips":["Never hand-edit the serialized ATN literal inside generated files","Keep generated files byte-identical to fresh generation (diff in CI)","Match tool and runtime versions"],"tags":["antlr4","python","atn","corrupt-data","deserialization"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}