alibaba/DataX · error · ValueError

index must be as long as the number of data rows

Error message

index must be as long as the number of data rows

What it means

ValueError from _prepend_row_index in the vendored tabulate.py used by otsstreamreader's tools: the caller passed an 'index' sequence whose length differs from the number of data rows. tabulate refuses to zip mismatched lengths instead of silently truncating.

Solutions

  1. Drop the index argument and let tabulate compute/omit it.
  2. Recompute the index after filtering: pass index=range(len(rows)) or the same-length sequence.
  3. Convert the data to a plain list of lists before calling tabulate so only one length source exists.

Example fix

# before
tabulate(rows, headers=cols, index=row_ids)  # row_ids stale after rows = [r for r in rows if ok(r)]
# after
rows = [r for r in rows if ok(r)]
tabulate(rows, headers=cols, index=list(range(len(rows))))
Defensive patterns

Strategy: validation

Validate before calling

if index is not None and len(index) != len(rows):
    raise ValueError('fix caller: index len %d != rows len %d' % (len(index), len(rows)))

Type guard

def index_matches(rows, index):
    return index is None or index is False or len(index) == len(rows)

Prevention

When it happens

Trigger: Calling tabulate(tabular_data, ..., index=seq) where len(seq) != len(rows). With DataFrames tabulate itself derives index = list(df.index), so a mismatch means the object is DataFrame-like but its .values rows count differs from its .index length (pandas version heuristic mismatch).

Common situations: Passing a hand-built index list (e.g. row numbers 0..n-1 computed before filtering rows) alongside data that was filtered afterwards; vendored tabulate (0.7.x era) hitting newer pandas whose .values shape differs; using a DataFrame subclass.

Related errors


AI-assisted analysis of alibaba/DataX@80ec23d5c5 (2026-08-14). Data as JSON: /api/errors/de4e6506f9c2a18c. Report an issue: GitHub.

Appendix: source

Thrown at otsstreamreader/tools/tabulate.py:633

    width += len(header) - visible_width
    if alignment == "left":
        return _padright(width, header)
    elif alignment == "center":
        return _padboth(width, header)
    elif not alignment:
        return "{0}".format(header)
    else:
        return _padleft(width, header)


def _prepend_row_index(rows, index):
    """Add a left-most index column."""
    if index is None or index is False:
        return rows
    if len(index) != len(rows):
        print('index=', index)
        print('rows=', rows)
        raise ValueError('index must be as long as the number of data rows')
    rows = [[v]+list(row) for v,row in zip(index, rows)]
    return rows


def _bool(val):
    "A wrapper around standard bool() which doesn't throw on NumPy arrays"
    try:
        return bool(val)
    except ValueError:  # val is likely to be a numpy array with many elements
        return False


def _normalize_tabular_data(tabular_data, headers, showindex="default"):
    """Transform a supported data type to a list of lists, and a list of headers.

    Supported tabular data types:

    * list-of-lists or another iterable of iterables

View on GitHub (pinned to 80ec23d5c5)