unslothai/unsloth · error · ValueError

An audio sample should have one of 'path' or 'bytes' but bot

Error message

An audio sample should have one of 'path' or 'bytes' but both are None in {value}.

What it means

ValueError from the patched Audio.decode_example when a sample dict has both value['path'] and value['bytes'] equal to None. The decoder needs exactly one source — in-memory bytes or a resolvable path — and a sample with neither is structurally invalid. This mirrors upstream HF datasets' validation and fires before any soundfile/xopen work begins.

Source

Thrown at studio/backend/utils/datasets/audio_decode.py:85

    self,
    value: dict,
    token_per_repo_id: Optional[dict] = None,
) -> dict:
    """Stand-in for `datasets.Audio.decode_example` that never needs FFmpeg."""
    import io

    import numpy as np
    import soundfile as sf
    from datasets.download.download_config import DownloadConfig
    from datasets.utils.file_utils import is_local_path, xopen

    if not self.decode:
        raise RuntimeError(
            "Decoding is disabled for this feature. Please use Audio(decode=True) instead."
        )
    path, raw = value["path"], value["bytes"]
    if path is None and raw is None:
        raise ValueError(
            f"An audio sample should have one of 'path' or 'bytes' but both are None in {value}."
        )

    if raw is not None:
        source: Any = io.BytesIO(raw)
    elif is_local_path(path):
        source = path
    else:
        source = xopen(
            path,
            "rb",
            download_config = DownloadConfig(token = _token_for_url(path, token_per_repo_id)),
        )

    array, sampling_rate = sf.read(source, dtype = "float32", always_2d = False)
    if array.ndim > 1:
        # soundfile returns (frames, channels); torchcodec returns (channels, frames).
        array = np.mean(array, axis = -1)

View on GitHub (pinned to 203007d190)

Solutions

  1. Filter the bad rows before decoding: dataset.filter(lambda r: r['audio']['path'] is not None or r['audio']['bytes'] is not None)
  2. Repair the source dataset so each audio row carries either a valid path or bytes
  3. If building the dataset yourself, ensure exactly one of path/bytes is populated when constructing audio samples

Example fix

# before
dataset = dataset.map(lambda r: {'audio': feature.decode_example(r['audio'], ...)})

# after
dataset = dataset.filter(
    lambda r: (r['audio'] or {}).get('path') is not None
    or (r['audio'] or {}).get('bytes') is not None
)
dataset = dataset.map(lambda r: {'audio': feature.decode_example(r['audio'], ...)})
Defensive patterns

Strategy: validation

Validate before calling

def audio_sample_is_valid(sample) -> bool:
    if not isinstance(sample, dict):
        return False
    return sample.get("path") is not None or sample.get("bytes") is not None

Type guard

def has_audio_source(value: dict) -> bool:
    """Narrows an audio field to 'decodable' — exactly one of path/bytes set."""
    return (
        isinstance(value, dict)
        and (value.get("path") is not None) ^ (value.get("bytes") is not None)
    )

Try / catch

try:
    decoded = feature.decode_example(sample)
except ValueError as e:
    if "both are None" in str(e):
        skip_row_and_log(sample)  # data defect — do not retry
    else:
        raise

Prevention

When it happens

Trigger: Rows where the audio field is {'path': None, 'bytes': None} — common when datasets built from a source with missing files are materialized, or when a map/flatten step constructs the dict and drops both keys' values.

Common situations: Corrupt or truncated dataset builds (upload interrupted so bytes never landed), parquet rows written with explicit nulls, datasets assembled from JSON where the audio entry was null, caching bugs that null out path fields.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/e5640e4a0016fb38. Report an issue: GitHub.