apache/beam · error · ValueError

Cannot skip negative number of header lines

Error message

Cannot skip negative number of header lines: %d

What it means

ReadFromText's __init__ validates skip_header_lines and raises this ValueError when a negative value is passed. Skipping a negative number of header lines is meaningless, so it is rejected at construction time; values above 10 only produce a performance warning.

Solutions

  1. Pass 0 (the default) or a positive integer for skip_header_lines.
  2. Validate/sanitize the value before constructing: max(0, int(configured_value)).
  3. Fix the pipeline option default so 'unset' maps to 0 rather than -1.
  4. If headers must be conditionally skipped, branch between ReadFromText(..., skip_header_lines=0) and the skipping variant instead of negating.

Example fix

// before
ReadFromText('data.csv', skip_header_lines=-1)
// after
ReadFromText('data.csv', skip_header_lines=max(0, requested_header_lines))
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(skip_header_lines, int) or skip_header_lines < 0:
    raise ValueError(f'skip_header_lines must be >= 0, got {skip_header_lines!r}')

Type guard

def is_valid_skip_header_lines(v):
    return isinstance(v, int) and not isinstance(v, bool) and v >= 0

Try / catch

try:
    transform = ReadFromText(file_pattern, skip_header_lines=skip_header_lines)
except ValueError as e:
    if 'skip negative number of header lines' in str(e):
        logging.error('Bad skip_header_lines: %s', skip_header_lines)
        transform = ReadFromText(file_pattern, skip_header_lines=0)

Prevention

When it happens

Trigger: Creating ReadFromText(file_pattern, skip_header_lines=-1) (or any negative int), often from a config value, CLI flag, or computed expression like n-1 that underflows.

Common situations: YAML/pipeline options where skip_header_lines defaults to -1 meaning 'unset'; arithmetic like header_count-1 with header_count=0; typos passing skip_footer=-1 style values to the wrong parameter.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/88ee5334a70ac2c2. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/io/textio.py:154

        delimiter, can also escape itself.
    Raises:
      ValueError: if skip_lines is negative.

    Please refer to documentation in class `ReadFromText` for the rest
    of the arguments.
    """
    super().__init__(
        file_pattern,
        min_bundle_size,
        compression_type=compression_type,
        validate=validate)

    self._strip_trailing_newlines = strip_trailing_newlines
    self._compression_type = compression_type
    self._coder = coder
    self._buffer_size = buffer_size
    if skip_header_lines < 0:
      raise ValueError(
          'Cannot skip negative number of header lines: %d' % skip_header_lines)
    elif skip_header_lines > 10:
      _LOGGER.warning(
          'Skipping %d header lines. Skipping large number of header '
          'lines might significantly slow down processing.')
    self._skip_header_lines = skip_header_lines
    self._header_matcher, self._header_processor = header_processor_fns
    if delimiter is not None:
      if not isinstance(delimiter, bytes) or len(delimiter) == 0:
        raise ValueError('Delimiter must be a non-empty bytes sequence.')
      if self._is_self_overlapping(delimiter):
        raise ValueError('Delimiter must not self-overlap.')
    self._delimiter = delimiter
    if escapechar is not None:
      if not (isinstance(escapechar, bytes) and len(escapechar) == 1):
        raise ValueError(
            "escapechar must be bytes of size 1: '%s'" % escapechar)
    self._escapechar = escapechar

View on GitHub (pinned to 12126d8942)