larksuite/cli · error · ValueError

Invalid column: {col}

Error message

Invalid column: {col}

What it means

col_to_index converts a column label like 'AB' to its 1-based numeric index and only accepts ASCII letters A-Z (case-insensitive). Any character outside A-Z after stripping/uppercasing makes the label unconvertible, so it raises this ValueError. Callers feed it column parts parsed out of range strings or CSV indices, so this guards against malformed range input.

Source

Thrown at skills/lark-sheets/scripts/lark_sheet_range.py:35

    start_row: int
    start_col: int
    end_row: int
    end_col: int

    @property
    def row_count(self) -> int:
        return self.end_row - self.start_row + 1

    @property
    def col_count(self) -> int:
        return self.end_col - self.start_col + 1


def col_to_index(col: str) -> int:
    value = 0
    for char in col.strip().upper():
        if not ("A" <= char <= "Z"):
            raise ValueError(f"Invalid column: {col}")
        value = value * 26 + (ord(char) - ord("A") + 1)
    if value <= 0:
        raise ValueError(f"Invalid column: {col}")
    return value


def index_to_col(index: int) -> str:
    if index < 1:
        raise ValueError(f"Column index must be >= 1: {index}")
    chars = []
    n = index
    while n:
        n, rem = divmod(n - 1, 26)
        chars.append(chr(ord("A") + rem))
    return "".join(reversed(chars))


def parse_cell(cell_ref: str) -> tuple[int, int]:

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Strip non-letter characters first: col.strip('$ 0123456789') or extract only the leading letters from the cell reference with a regex like ^([A-Za-z]+).
  2. Validate user-supplied ranges before calling, e.g. re.fullmatch(r'[A-Za-z]+', col).
  3. Fix the upstream range parser so cell references are split into (letters, digits) parts correctly.

Example fix

# before
col_to_index("$AB$12")  # ValueError: Invalid column: $AB$12
# after
import re
m = re.match(r"^([A-Za-z]+)", "$AB$12")
col_to_index(m.group(1))  # -> 28
Defensive patterns

Strategy: validation

Validate before calling

import re

def is_valid_column(col: str) -> bool:
    return bool(re.fullmatch(r"[A-Za-z]+", (col or "").strip()))

Type guard

import re

def is_column_label(s: object) -> bool:
    return isinstance(s, str) and bool(re.fullmatch(r"[A-Za-z]+", s.strip()))

Try / catch

try:
    idx = col_to_index(col)
except ValueError as e:
    if "Invalid column" in str(e):
        m = re.match(r"^([A-Za-z]+)", col or "")
        idx = col_to_index(m.group(1)) if m else 1
    else:
        raise

Prevention

When it happens

Trigger: Passing a column string containing digits, '$' (as in '$A$1'), whitespace within, '.', '_', or non-Latin characters to col_to_index, e.g. col_to_index('$A'), col_to_index('A1'), col_to_index('列A').

Common situations: Parsing raw A1 notation that still contains $ anchors or row digits; user-supplied range strings like 'A1:B2' split incorrectly so digits leak into the column part; localized column letters from non-English locales.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/1ab02822d0b31812. Report an issue: GitHub.