{"record":{"id":"de4e6506f9c2a18c","repo":"alibaba/DataX","slug":"index-must-be-as-long-as-the-number-of-data-rows","errorCode":null,"errorMessage":"index must be as long as the number of data rows","messagePattern":"index must be as long as the number of data rows","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"otsstreamreader/tools/tabulate.py","lineNumber":633,"sourceCode":"    width += len(header) - visible_width\n    if alignment == \"left\":\n        return _padright(width, header)\n    elif alignment == \"center\":\n        return _padboth(width, header)\n    elif not alignment:\n        return \"{0}\".format(header)\n    else:\n        return _padleft(width, header)\n\n\ndef _prepend_row_index(rows, index):\n    \"\"\"Add a left-most index column.\"\"\"\n    if index is None or index is False:\n        return rows\n    if len(index) != len(rows):\n        print('index=', index)\n        print('rows=', rows)\n        raise ValueError('index must be as long as the number of data rows')\n    rows = [[v]+list(row) for v,row in zip(index, rows)]\n    return rows\n\n\ndef _bool(val):\n    \"A wrapper around standard bool() which doesn't throw on NumPy arrays\"\n    try:\n        return bool(val)\n    except ValueError:  # val is likely to be a numpy array with many elements\n        return False\n\n\ndef _normalize_tabular_data(tabular_data, headers, showindex=\"default\"):\n    \"\"\"Transform a supported data type to a list of lists, and a list of headers.\n\n    Supported tabular data types:\n\n    * list-of-lists or another iterable of iterables","sourceCodeStart":615,"sourceCodeEnd":651,"githubUrl":"https://github.com/alibaba/DataX/blob/80ec23d5c5328eb90ca364d2749e92dfaf44541e/otsstreamreader/tools/tabulate.py#L615-L651","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Drop the index argument and let tabulate compute/omit it.","Recompute the index after filtering: pass index=range(len(rows)) or the same-length sequence.","Convert the data to a plain list of lists before calling tabulate so only one length source exists."],"exampleFix":"# before\ntabulate(rows, headers=cols, index=row_ids)  # row_ids stale after rows = [r for r in rows if ok(r)]\n# after\nrows = [r for r in rows if ok(r)]\ntabulate(rows, headers=cols, index=list(range(len(rows))))","handlingStrategy":"validation","validationCode":"if index is not None and len(index) != len(rows):\n    raise ValueError('fix caller: index len %d != rows len %d' % (len(index), len(rows)))","typeGuard":"def index_matches(rows, index):\n    return index is None or index is False or len(index) == len(rows)","tryCatchPattern":null,"preventionTips":["Derive the index from the same filtering pass that produces rows.","Prefer omitting index and letting tabulate generate row numbers."],"tags":["python","tabulate","dev-tools","validation"],"backgroundTag":null,"analyzedSha":"80ec23d5c5328eb90ca364d2749e92dfaf44541e","analyzedAt":"2026-08-14T15:33:51.187Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}