{"record":{"id":"7a748f8ace325190","repo":"pola-rs/polars","slug":"empty-data-from-context-hint","errorCode":null,"errorMessage":"empty data from {context}{hint}","messagePattern":"empty data from (.+?)(.+?)","errorType":"exception","errorClass":"NoDataError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/_utils.py","lineNumber":310,"sourceCode":"                    BytesIO(f.read().encode(\"utf8\")),\n                    context=f\"{file!r}\",\n                    raise_if_empty=raise_if_empty,\n                )\n\n    return managed_file(file)\n\n\ndef _check_empty(\n    b: BytesIO, *, context: str, raise_if_empty: bool, read_position: int | None = None\n) -> BytesIO:\n    if raise_if_empty and b.getbuffer().nbytes == 0:\n        hint = (\n            f\" (buffer position = {read_position}; try seek(0) before reading?)\"\n            if context in (\"StringIO\", \"BytesIO\") and read_position\n            else \"\"\n        )\n        msg = f\"empty data from {context}{hint}\"\n        raise NoDataError(msg)\n    return b\n\n\ndef looks_like_url(path: str) -> bool:\n    return re.match(r\"^(ht|f)tps?://\", path, re.IGNORECASE) is not None\n\n\ndef process_file_url(path: str, encoding: str | None = None) -> BytesIO:\n    from urllib.request import urlopen\n\n    with urlopen(path) as f:\n        if not encoding or encoding in {\"utf8\", \"utf8-lossy\"}:\n            return BytesIO(f.read())\n        else:\n            return BytesIO(f.read().decode(encoding).encode(\"utf8\"))\n\n\ndef is_glob_pattern(file: str) -> bool:","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/io/_utils.py#L292-L328","documentation":"_check_empty (py-polars/src/polars/io/_utils.py:301-312) guards eager readers against zero-byte input: a bytes object, StringIO, BytesIO, local file, or HTTP body that yields an empty buffer raises polars.exceptions.NoDataError when raise_if_empty=True (the default). For StringIO/BytesIO sources whose read position is past the data, the message appends a hint ('buffer position = N; try seek(0) before reading?') pointing at a consumed buffer rather than truly empty data.","triggerScenarios":"pl.read_csv(io.StringIO('')) or pl.read_csv(io.BytesIO()) with defaults; re-reading the same BytesIO twice without seek(0) - the first read moves the position to EOF, so the second read sees 'empty' data and the hint fires; reading a 0-byte file left by a failed upstream job; a URL that returned an empty body.","commonSituations":"Pipelines where a source system occasionally emits empty extracts; test code reusing one buffer across multiple read calls; HTTP downloads that succeeded status-wise but returned no bytes.","solutions":["If empty input is legitimate, pass raise_if_empty=False and handle the empty result","Reset buffers before reading: buf.seek(0) - this is what the hint suggests","Skip empty files upstream: if path.stat().st_size == 0: continue","Investigate the producer that wrote/downloaded a 0-byte payload"],"exampleFix":"# before\nbuf = io.BytesIO(payload)  # payload may be b\"\"\ndf = pl.read_csv(buf)  # NoDataError when empty\n# after\nbuf = io.BytesIO(payload)\ndf = pl.read_csv(buf, raise_if_empty=False) if buf.getbuffer().nbytes == 0 else pl.read_csv(buf)","handlingStrategy":"validation","validationCode":"import io\n\ndef ensure_non_empty(source) -> None:\n    if isinstance(source, (io.StringIO, io.BytesIO)):\n        empty = source.seek(0, io.SEEK_END) == 0 if source.seekable() else False\n        source.seek(0)\n        if empty:\n            raise ValueError(\"empty input buffer\")\n    elif hasattr(source, \"read\"):\n        source.seek(0)\n        if not source.read(1):\n            source.seek(0)\n            raise ValueError(\"empty input stream\")\n            ","typeGuard":null,"tryCatchPattern":"from polars.exceptions import NoDataError\n\ntry:\n    df = pl.read_csv(source)\nexcept NoDataError:\n    df = pl.DataFrame()  # or skip/flag this file","preventionTips":["Call buf.seek(0) on any reused StringIO/BytesIO before handing it to polars","Size-check files (path.stat().st_size == 0) before batch reads","Catch polars.exceptions.NoDataError specifically, not bare Exception"],"tags":["polars","io","empty-data","nodataerror","buffer"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}