{"record":{"id":"48764934d607251e","repo":"larksuite/cli","slug":"invalid-cell-reference-cell-ref","errorCode":null,"errorMessage":"Invalid cell reference: {cell_ref}","messagePattern":"Invalid cell reference: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/lark-sheets/scripts/lark_sheet_range.py","lineNumber":56,"sourceCode":"        raise ValueError(f\"Invalid column: {col}\")\n    return value\n\n\ndef index_to_col(index: int) -> str:\n    if index < 1:\n        raise ValueError(f\"Column index must be >= 1: {index}\")\n    chars = []\n    n = index\n    while n:\n        n, rem = divmod(n - 1, 26)\n        chars.append(chr(ord(\"A\") + rem))\n    return \"\".join(reversed(chars))\n\n\ndef parse_cell(cell_ref: str) -> tuple[int, int]:\n    match = CELL_RE.match(cell_ref.strip())\n    if not match:\n        raise ValueError(f\"Invalid cell reference: {cell_ref}\")\n    col, row = match.groups()\n    return int(row), col_to_index(col)\n\n\ndef _parse_endpoint(endpoint: str) -> tuple[str, int, int] | tuple[str, int]:\n    cell = CELL_RE.match(endpoint)\n    if cell:\n        col, row = cell.groups()\n        return \"cell\", int(row), col_to_index(col)\n    row = ROW_RE.match(endpoint)\n    if row:\n        return \"row\", int(row.group(1))\n    column = COLUMN_RE.match(endpoint)\n    if column:\n        return \"column\", col_to_index(column.group(1))\n    raise ValueError(f\"Invalid A1 range endpoint: {endpoint}\")\n\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/skills/lark-sheets/scripts/lark_sheet_range.py#L38-L74","documentation":"parse_cell() validates a single cell reference against CELL_RE (^$?[A-Za-z]+$?[1-9][0-9]*$) and raises ValueError when the string is not a well-formed A1-style cell like 'A1', '$B$2', or 'AA10'. It returns (row, col) 1-based integers; any string that doesn't match the pattern is rejected before any API call.","triggerScenarios":"Calling parse_cell with an empty string, a bare column like 'A', a bare row like '5', a 0 row ('A0'), a range with ':' (e.g. 'A1:B2'), a sheet-qualified ref ('Sheet1!A1'), lowercase digits ('a1' is fine, but 'a 1' or 'A1 ' beyond strip, '1A', 'AB1C', 'A-1', or a whole range string passed instead of one cell).","commonSituations":"Passing a full range expression (A1:B2) where a single cell is expected; passing 'Sheet1!A1' without stripping the sheet prefix; 0-based or 0-indexed coordinates from code that assumed A0 exists; whitespace or invisible characters inside the ref; user config storing a column letter only.","solutions":["Strip sheet prefixes and whitespace: pass only the cell portion, e.g. ref.rsplit('!', 1)[-1].strip() before parse_cell.","Verify the ref matches ^\\$?[A-Za-z]+\\$?[1-9][0-9]*$ — fix 0-based rows (A0 → A1) and swap reversed refs like 1A → A1.","If you actually have a range, use parse_range() instead, or split on ':' and pass each endpoint to parse_cell.","Sanitize hidden characters (non-breaking spaces, full-width digits) from the input before parsing."],"exampleFix":"// before\nparse_cell(\"Sheet1!A1:B2\")   # Invalid cell reference: Sheet1!A1:B2\nparse_cell(\"A0\")            # Invalid cell reference: A0\n// after\nref = \"Sheet1!A1:B2\".rsplit(\"!\", 1)[-1]\nstart, end = ref.split(\":\")\nparse_cell(start)  # (1, 1)\nparse_cell(end)    # (2, 2)\nparse_cell(\"A1\")   # zero-indexed A0 corrected to A1","handlingStrategy":"validation","validationCode":"import re\nCELL_RE = re.compile(r\"^\\$?[A-Za-z]+\\$?[1-9][0-9]*$\")\ndef is_cell(ref: str) -> bool:\n    return bool(CELL_RE.match(ref.strip().rsplit(\"!\", 1)[-1]))\n# before: if not is_cell(user_ref): raise ValueError(f\"bad cell: {user_ref!r}\")\n# then: parse_cell(user_ref)","typeGuard":"import re\n_CELL = re.compile(r\"^\\$?[A-Za-z]+\\$?[1-9][0-9]*$\")\ndef as_cell(ref: str) -> tuple[int, int] | None:\n    if not _CELL.match(ref.strip().rsplit(\"!\", 1)[-1]):\n        return None\n    from lark_sheet_range import parse_cell\n    return parse_cell(ref)","tryCatchPattern":"from lark_sheet_range import parse_cell\ntry:\n    row, col = parse_cell(cell_ref)\nexcept ValueError as e:\n    print(f\"Skipping malformed cell ref {cell_ref!r}: {e}\")\n    row = col = None","preventionTips":["Strip sheet prefixes and whitespace (rsplit('!', 1)[-1].strip()) before parse_cell.","Never pass a range containing ':' to parse_cell — split it and parse endpoints separately.","Remember rows are 1-based; convert 0-based indexes with +1 before building the ref.","Use index_to_col(col_index) + str(row) to construct refs instead of string concatenation of mixed types."],"tags":["python","input-validation","a1-notation","valueerror"],"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"}