pola-rs/polars · error · NoDataError

empty data from {context}{hint}

Error message

empty data from {context}{hint}

What it means

_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.

Source

Thrown at py-polars/src/polars/io/_utils.py:310

                    BytesIO(f.read().encode("utf8")),
                    context=f"{file!r}",
                    raise_if_empty=raise_if_empty,
                )

    return managed_file(file)


def _check_empty(
    b: BytesIO, *, context: str, raise_if_empty: bool, read_position: int | None = None
) -> BytesIO:
    if raise_if_empty and b.getbuffer().nbytes == 0:
        hint = (
            f" (buffer position = {read_position}; try seek(0) before reading?)"
            if context in ("StringIO", "BytesIO") and read_position
            else ""
        )
        msg = f"empty data from {context}{hint}"
        raise NoDataError(msg)
    return b


def looks_like_url(path: str) -> bool:
    return re.match(r"^(ht|f)tps?://", path, re.IGNORECASE) is not None


def process_file_url(path: str, encoding: str | None = None) -> BytesIO:
    from urllib.request import urlopen

    with urlopen(path) as f:
        if not encoding or encoding in {"utf8", "utf8-lossy"}:
            return BytesIO(f.read())
        else:
            return BytesIO(f.read().decode(encoding).encode("utf8"))


def is_glob_pattern(file: str) -> bool:

View on GitHub (pinned to df599052da)

Solutions

  1. If empty input is legitimate, pass raise_if_empty=False and handle the empty result
  2. Reset buffers before reading: buf.seek(0) - this is what the hint suggests
  3. Skip empty files upstream: if path.stat().st_size == 0: continue
  4. Investigate the producer that wrote/downloaded a 0-byte payload

Example fix

# before
buf = io.BytesIO(payload)  # payload may be b""
df = pl.read_csv(buf)  # NoDataError when empty
# after
buf = io.BytesIO(payload)
df = pl.read_csv(buf, raise_if_empty=False) if buf.getbuffer().nbytes == 0 else pl.read_csv(buf)
Defensive patterns

Strategy: validation

Validate before calling

import io

def ensure_non_empty(source) -> None:
    if isinstance(source, (io.StringIO, io.BytesIO)):
        empty = source.seek(0, io.SEEK_END) == 0 if source.seekable() else False
        source.seek(0)
        if empty:
            raise ValueError("empty input buffer")
    elif hasattr(source, "read"):
        source.seek(0)
        if not source.read(1):
            source.seek(0)
            raise ValueError("empty input stream")
            

Try / catch

from polars.exceptions import NoDataError

try:
    df = pl.read_csv(source)
except NoDataError:
    df = pl.DataFrame()  # or skip/flag this file

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/7a748f8ace325190. Report an issue: GitHub.