{"record":{"id":"2db6f89cbf1314fb","repo":"larksuite/cli","slug":"csv-get-truncated-the-requested-range-at-source","errorCode":null,"errorMessage":"+csv-get truncated the requested range at {source_range}; narrow --range before profiling","messagePattern":"\\+csv-get truncated the requested range at (.+?); narrow --range before profiling","errorType":"exception","errorClass":"LarkCliError","httpStatus":null,"severity":"error","filePath":"skills/lark-sheets/scripts/lark_profile_table.py","lineNumber":550,"sourceCode":"        raise ValueError(\"--header-scan-rows must be at least 1\")\n    csv_data = envelope_data(\n        run_sheets(\n            \"+csv-get\",\n            url=args.url,\n            spreadsheet_token=args.spreadsheet_token,\n            sheet_id=args.sheet_id,\n            sheet_name=args.sheet_name,\n            flags={\n                \"range\": args.range,\n                \"max_chars\": args.max_chars,\n                \"skip_hidden\": True if args.skip_hidden else None,\n            },\n            timeout=args.timeout,\n        )\n    )\n    source_range = str(csv_data.get(\"actual_range\") or args.range)\n    if csv_data.get(\"has_more\"):\n        raise LarkCliError(\n            f\"+csv-get truncated the requested range at {source_range}; narrow --range before profiling\"\n        )\n    grid = parse_annotated_csv(\n        csv_data.get(\"annotated_csv\", \"\"),\n        csv_data.get(\"col_indices\"),\n        csv_data.get(\"row_indices\"),\n        source_range,\n    )\n    if grid.row_numbers_inferred:\n        warnings.append(\"CSV row numbers were inferred from the requested range\")\n    hidden_rows: list[int] = []\n    hidden_columns: list[str] = []\n    all_hidden_columns: list[str] | None = None\n    # Fetched in BOTH modes. Under --skip-hidden the hidden rows/columns are\n    # absent from the grid, so hidden_rows/hidden_columns (which are scoped to\n    # what the grid contains) come back empty and no warning fires — but the\n    # write hints still need to know where the hidden columns are, or\n    # safe_append_col can point at one that holds data. all_hidden_columns is","sourceCodeStart":532,"sourceCodeEnd":568,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/skills/lark-sheets/scripts/lark_profile_table.py#L532-L568","documentation":"profile_table requires the FULL requested range to profile accurately. When the +csv-get call reports has_more=true, the returned data was truncated at actual_range, so profiling would run on partial data; the script refuses and tells you to narrow --range. It fails fast instead of producing misleading statistics.","triggerScenarios":"Running profile_table against a range larger than what +csv-get can return in one response: args.range spans too many cells/rows so csv_data['has_more'] is true.","commonSituations":"Profiling an entire huge sheet (e.g. --range A1:Z100000 on a sheet with tens of thousands of rows); downstream limits on the CSV export lowered so previously-fine ranges now truncate; a spreadsheet_token/sheet_id pointing at a much bigger sheet than expected.","solutions":["Pass a narrower --range that fits in one response, e.g. split A1:Z50000 into A1:Z20000, A20001:Z40000, etc.","Profile per sheet/sub-range in a loop, merging results yourself.","If the range looks right, verify the sheet dimensions; the truncation point is reported in the error (actual_range)."],"exampleFix":"# before\nrun([\"lark\", \"sheets\", \"profile-table\", \"--range\", \"A1:Z100000\"])\n# after\nrun([\"lark\", \"sheets\", \"profile-table\", \"--range\", \"A1:Z10000\"])\nrun([\"lark\", \"sheets\", \"profile-table\", \"--range\", \"A10001:Z20000\"])","handlingStrategy":"validation","validationCode":"def safe_range(sheet_rows: int, sheet_cols: int, max_cells: int = 1_000_000) -> str:\n    if sheet_rows * sheet_cols > max_cells:\n        raise ValueError(f\"Range {sheet_rows}x{sheet_cols} exceeds {max_cells} cells; narrow --range\")\n    return f\"A1:{index_to_col(sheet_cols)}{sheet_rows}\"","typeGuard":null,"tryCatchPattern":"try:\n    data, warnings = profile_table(args)\nexcept LarkCliError as e:\n    if \"truncated the requested range\" in str(e):\n        # narrow the range per the reported actual_range and retry in chunks\n        args.range = narrow_range(args.range)\n        data, warnings = profile_table(args)\n    else:\n        raise","preventionTips":["Estimate cell count (rows x cols) before profiling and split ranges over the response limit.","Profile sheet-by-sheet instead of whole-workbook ranges.","Watch has_more/actual_range in +csv-get output during exploration to size ranges correctly."],"tags":["cli","sheets","range-truncation","python"],"backgroundTag":"result-truncated-narrow-scope","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}