{"record":{"id":"89bb6a4eefebc479","repo":"Textualize/textual","slug":"end-of-file-reached","errorCode":null,"errorMessage":"end of file reached","messagePattern":"end of file reached","errorType":"exception","errorClass":"ParseError","httpStatus":null,"severity":"error","filePath":"src/textual/_parser.py","lineNumber":78,"sourceCode":"            self._timeout_time = None\n            self._awaiting = self._gen.throw(ParseTimeout())\n            while self._tokens:\n                yield self._tokens.popleft()\n\n    def feed(self, data: str) -> Iterable[T]:\n        \"\"\"Feed data to be parsed.\n\n        Args:\n            data: Data to parser.\n\n        Raises:\n            ParseError: If the data could not be parsed.\n\n        Yields:\n            T: A generic data type.\n        \"\"\"\n        if self._eof:\n            raise ParseError(\"end of file reached\") from None\n\n        tokens = self._tokens\n        popleft = tokens.popleft\n\n        if not data:\n            self._eof = True\n            try:\n                self._gen.throw(ParseEOF())\n            except StopIteration:\n                pass\n            while tokens:\n                yield popleft()\n            return\n\n        pos = 0\n        data_size = len(data)\n\n        while tokens:","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/_parser.py#L60-L96","documentation":"Raised by Parser.feed when more data is pushed into the tokenizer after it has already been signaled that input ended (an empty data chunk sets _eof). It indicates a state-machine misuse of the incremental parser rather than malformed input.","triggerScenarios":"Calling feed('') once (which sets self._eof = True) and then calling feed(data) again on the same Parser instance.","commonSituations":"Tokenizing CSS/content in a loop where an empty chunk terminates input accidentally; reusing a single Parser object across multiple documents; feeding leftover bytes after signaling EOF.","solutions":["Do not pass an empty string to feed unless you truly intend to end input; skip falsy chunks before feeding","Use a fresh Parser instance for each new document/stream","If streaming from a file/network, only send a final empty/EOF signal once, at true end of stream"],"exampleFix":"# before\nfor chunk in chunks:\n    parser.feed(chunk)  # chunk may be ''\n\n# after\nfor chunk in chunks:\n    if chunk:\n        parser.feed(chunk)\nparser.feed(\"\")  # signal EOF exactly once","handlingStrategy":"validation","validationCode":"if parser._eof:\n    parser = Parser(...)  # reset instead of feeding","typeGuard":null,"tryCatchPattern":"try:\n    parser.feed(data)\nexcept ParseError:\n    parser = Parser(...)  # restart with fresh state","preventionTips":["Never feed empty chunks except to signal true EOF","One Parser per document","Skip falsy chunks in streaming loops"],"tags":["parser","state-machine","eof","tokenize"],"backgroundTag":"parser-state-misuse","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}