larksuite/cli · error · ValueError
Range needs a maximum row: {range_ref}
Error message
Range needs a maximum row: {range_ref} What it means
parse_range() raises this when an open-ended column range like 'A:C' is given but the caller did not pass max_row. A column-only range has no bottom edge, so the library requires the caller's actual row count instead of guessing a spreadsheet-wide limit.
Source
Thrown at skills/lark-sheets/scripts/lark_sheet_range.py:118
_, row, col = start
return RangeBounds(row, col, row, col)
if start[0] == end[0] == "cell":
_, start_row, start_col = start
_, end_row, end_col = end
elif start[0] == end[0] == "row":
_, start_row = start
_, end_row = end
start_col = 1
if max_col is None:
raise ValueError(f"Range needs a maximum column: {range_ref}")
end_col = max_col
elif start[0] == end[0] == "column":
_, start_col = start
_, end_col = end
start_row = 1
if max_row is None:
raise ValueError(f"Range needs a maximum row: {range_ref}")
end_row = max_row
elif start[0] == "cell" and end[0] == "column":
_, start_row, start_col = start
_, end_col = end
if max_row is None:
raise ValueError(f"Range needs a maximum row: {range_ref}")
end_row = max(start_row, max_row)
elif start[0] == "cell" and end[0] == "row":
_, start_row, start_col = start
_, end_row = end
if max_col is None:
raise ValueError(f"Range needs a maximum column: {range_ref}")
end_col = max(start_col, max_col)
else:
raise ValueError(f"Invalid A1 range: {range_ref}")
return RangeBounds(min(start_row, end_row), min(start_col, end_col), max(start_row, end_row), max(start_col, end_col))
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Pass max_row explicitly: parse_range('A:C', max_row=200) with the actual row count.
- Use a closed cell range such as parse_range('A1:C200') so no dimension is needed.
- Fetch sheet dimensions first, then call parse_range with max_row set from them.
Example fix
// before
bounds = parse_range("A:C")
// after
bounds = parse_range("A:C", max_row=last_used_row) Defensive patterns
Strategy: validation
Validate before calling
import re
def is_open_col_range(ref: str) -> bool:
"""True if ref is column:column form and will require max_row."""
body = ref.strip().rsplit("!", 1)[-1]
parts = body.split(":")
col_re = re.compile(r"^\$?[A-Za-z]+$")
return len(parts) == 2 and all(col_re.match(p.strip()) for p in parts)
# call site
if is_open_col_range(ref):
assert max_row is not None, f"{ref} needs max_row"
bounds = parse_range(ref, max_row=max_row) Type guard
def needs_max_row(ref: str) -> bool:
body = ref.strip().rsplit("!", 1)[-1]
parts = body.split(":")
import re
col_re = re.compile(r"^\$?[A-Za-z]+$")
return len(parts) == 2 and bool(col_re.match(parts[0].strip()) and col_re.match(parts[-1].strip())) Try / catch
try:
bounds = parse_range(ref, max_row=max_row)
except ValueError as e:
if "maximum row" in str(e):
bounds = parse_range(ref, max_row=grid_row_count) # retry with fetched height
else:
raise Prevention
- Avoid whole-column ranges when the data height is known; write A1:C200 instead
- Fetch sheet dimensions before parsing ranges and pass them as max_row/max_col
- Document the accepted range grammar wherever users configure range strings
When it happens
Trigger: Calling parse_range('A:C') without max_row, or wrappers (parse_annotated_csv, _external_merge_anchors, build_occupancy, profile_grid) receiving a column-range while the fetched grid height is unknown.
Common situations: Configuring an export with a whole-column range ('B:D') before knowing how many rows the sheet has; scripts that hardcode column ranges but forget to thread the fetched row count into parse_range.
Related errors
- Range needs a maximum column: {range_ref}
- +csv-get truncated the requested range at {source_range}; na
- Invalid column: {col}
- Column index must be >= 1: {index}
- Row must be >= 1: {row}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/560fb47d71aacd33.
Report an issue: GitHub.