Textualize/rich · error · ValueError

unable to get the total number of bytes, please specify 'tot

Error message

unable to get the total number of bytes, please specify 'total'

What it means

Progress.wrap_file() needs a total byte count to build a progress bar. It first uses the explicit total= argument, then falls back to the task's existing .total (when task_id= is given). If both are None it raises ValueError telling you to specify 'total'. Unlike Progress.open(), wrap_file does not stat the file for you.

Source

Thrown at rich/progress.py:1267

            total (int, optional): Total number of bytes to read. This must be provided unless a task with a total is also given.
            task_id (TaskID): Task to track. Default is new task.
            description (str, optional): Description of task, if new task is created.

        Returns:
            BinaryIO: A readable file-like object in binary mode.

        Raises:
            ValueError: When no total value can be extracted from the arguments or the task.
        """
        # attempt to recover the total from the task
        total_bytes: Optional[float] = None
        if total is not None:
            total_bytes = total
        elif task_id is not None:
            with self._lock:
                total_bytes = self._tasks[task_id].total
        if total_bytes is None:
            raise ValueError(
                f"unable to get the total number of bytes, please specify 'total'"
            )

        # update total of task or create new task
        if task_id is None:
            task_id = self.add_task(description, total=total_bytes)
        else:
            self.update(task_id, total=total_bytes)

        return _Reader(file, self, task_id, close_handle=False)

    @typing.overload
    def open(
        self,
        file: Union[str, "PathLike[str]", bytes],
        mode: Literal["rb"],
        buffering: int = -1,
        encoding: Optional[str] = None,

View on GitHub (pinned to 9d8f9a372c)

Solutions

  1. Pass total= explicitly: progress.wrap_file(file, total=expected_size, task_id=tid).
  2. If the file is seekable, compute the size yourself: total=f.seek(0, os.SEEK_END); f.seek(0).
  3. If size is genuinely unknown, use add_task(total=None) with the wrapper omitted — rich renders an indeterminate (spinner) bar — or track completed bytes via progress.update().

Example fix

# before
reader = progress.wrap_file(f, task_id=tid)  # ValueError: unable to get total

# after
import os
total = os.fstat(f.fileno()).st_size
reader = progress.wrap_file(f, total=total, task_id=tid)
Defensive patterns

Strategy: validation

Validate before calling

import os

def wrap_with_total(progress, file, task_id=None, description='Reading'):
    total = getattr(file, 'total', None)
    if total is None and hasattr(file, 'fileno'):
        try:
            total = os.fstat(file.fileno()).st_size
        except (OSError, ValueError):
            total = 0
    if total is None:
        raise ValueError('cannot determine total size for wrap_file')
    return progress.wrap_file(file, total=total, task_id=task_id, description=description)

Try / catch

try:
    reader = progress.wrap_file(f, task_id=tid)
except ValueError:
    # fall back to indeterminate task
    tid = progress.add_task('reading', total=None)
    reader = f

Prevention

When it happens

Trigger: progress.wrap_file(file) with no total= and no task_id=; or progress.wrap_file(file, task_id=tid) where the referenced task was created without a total (e.g. add_task('x', total=None) or add_task with start=False and no total). Also when the caller assumed wrap_file would use file size automatically.

Common situations: Streaming a non-seekable object (BytesIO without total, a socket, a generator-backed file-like object) where size is unknowable; migrating from Progress.open() (which stats the file) to wrap_file() and dropping total=; using an indeterminate task and then passing it via task_id=.

Related errors


AI-assisted analysis of Textualize/rich@9d8f9a372c (2026-08-15). Data as JSON: /api/errors/de30cb58e78242b1. Report an issue: GitHub.