{"record":{"id":"268251e8ce44875d","repo":"larksuite/cli","slug":"row-must-be-1-row","errorCode":null,"errorMessage":"Row must be >= 1: {row}","messagePattern":"Row must be >= 1: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/lark-sheets/scripts/lark_sheet_range.py","lineNumber":139,"sourceCode":"        _, start_row, start_col = start\n        _, end_col = end\n        if max_row is None:\n            raise ValueError(f\"Range needs a maximum row: {range_ref}\")\n        end_row = max(start_row, max_row)\n    elif start[0] == \"cell\" and end[0] == \"row\":\n        _, start_row, start_col = start\n        _, end_row = end\n        if max_col is None:\n            raise ValueError(f\"Range needs a maximum column: {range_ref}\")\n        end_col = max(start_col, max_col)\n    else:\n        raise ValueError(f\"Invalid A1 range: {range_ref}\")\n    return RangeBounds(min(start_row, end_row), min(start_col, end_col), max(start_row, end_row), max(start_col, end_col))\n\n\ndef format_cell(row: int, col: int) -> str:\n    if row < 1:\n        raise ValueError(f\"Row must be >= 1: {row}\")\n    return f\"{index_to_col(col)}{row}\"\n\n\ndef format_range(start_row: int, start_col: int, end_row: int, end_col: int) -> str:\n    bounds = RangeBounds(\n        min(start_row, end_row),\n        min(start_col, end_col),\n        max(start_row, end_row),\n        max(start_col, end_col),\n    )\n    start = format_cell(bounds.start_row, bounds.start_col)\n    end = format_cell(bounds.end_row, bounds.end_col)\n    return start if start == end else f\"{start}:{end}\"\n\n\ndef iter_cells(bounds: RangeBounds):\n    for row in range(bounds.start_row, bounds.end_row + 1):\n        for col in range(bounds.start_col, bounds.end_col + 1):","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/skills/lark-sheets/scripts/lark_sheet_range.py#L121-L157","documentation":"format_cell() in lark_sheet_range.py validates that a row index is a positive 1-based integer before converting (row, col) to an A1 notation cell reference like \"B3\". Sheets use 1-based rows, so row 0 or negative rows cannot map to a valid A1 cell. The library raises ValueError immediately to prevent emitting a malformed range string to the Sheets API.","triggerScenarios":"Calling format_cell(row, col) with row < 1, e.g. format_cell(0, 1) or format_cell(-1, 5), typically from format_range or a caller passing a computed row that was decremented to 0.","commonSituations":"Developers converting 0-based array indices to A1 notation and forgetting the +1; off-by-one loops that decrement the row before formatting; slicing list rows with [start-1:end] and passing the adjusted index instead of the 1-based one.","solutions":["Pass a 1-based row: add 1 to any 0-based index before calling format_cell.","Clamp or validate computed rows: if row < 1, fix the loop/slice bounds that produced it instead of coercing.","If you truly need an open-ended range, use format_range with explicit bounds or pass a column-only boundary the range formatter supports, rather than row 0."],"exampleFix":"// before\nrow_idx = rows.index(target)  # 0-based\nref = format_cell(row_idx, col)  # ValueError: Row must be >= 1: 0\n\n// after\nref = format_cell(rows.index(target) + 1, col)  # 1-based A1 row","handlingStrategy":"validation","validationCode":"def safe_format_cell(row, col):\n    if not isinstance(row, int) or row < 1:\n        raise ValueError(f\"row must be a 1-based int >= 1, got {row!r}\")\n    return format_cell(row, col)","typeGuard":"def is_valid_row(row) -> bool:\n    return isinstance(row, int) and not isinstance(row, bool) and row >= 1","tryCatchPattern":"try:\n    ref = format_cell(row, col)\nexcept ValueError:\n    ref = format_cell(max(row, 1), col)  # or fix the index source","preventionTips":["Always convert 0-based indices with +1 immediately before A1 formatting.","Add an assert row >= 1 at the boundary where indices are computed.","Prefer format_range with explicit bounds over manual cell strings."],"tags":["python","validation","a1-notation","off-by-one"],"backgroundTag":"invalid-cell-reference","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"}