{"record":{"id":"11b106da6641e358","repo":"larksuite/cli","slug":"invalid-column-index-index","errorCode":null,"errorMessage":"Invalid column index: {index}","messagePattern":"Invalid column index: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/lark-sheets/scripts/lark_chart_layout_check.py","lineNumber":49,"sourceCode":"\nACTION = \"chart_layout_check\"\nDEFAULT_COLUMN_WIDTH = 105.0\nDEFAULT_ROW_HEIGHT = 27.0\n\n\ndef column_to_index(column: str) -> int:\n    value = 0\n    text = str(column).strip().upper()\n    if not text or not text.isalpha():\n        raise ValueError(f\"Invalid column: {column!r}\")\n    for char in text:\n        value = value * 26 + ord(char) - ord(\"A\") + 1\n    return value - 1\n\n\ndef index_to_column(index: int) -> str:\n    if index < 0:\n        raise ValueError(f\"Invalid column index: {index}\")\n    chars: list[str] = []\n    value = index + 1\n    while value:\n        value, remainder = divmod(value - 1, 26)\n        chars.append(chr(ord(\"A\") + remainder))\n    return \"\".join(reversed(chars))\n\n\ndef _span_bounds(span: str, *, columns: bool) -> tuple[int, int]:\n    start, separator, end = str(span).partition(\":\")\n    end = end if separator else start\n    if columns:\n        return column_to_index(start), column_to_index(end)\n    return int(start) - 1, int(end) - 1\n\n\ndef _size_edges(\n    groups: Any,","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/skills/lark-sheets/scripts/lark_chart_layout_check.py#L31-L67","documentation":"skillref.New rejects a mappings list where the same source reference appears more than once. Each From key must be unique so the remap projection is unambiguous; duplicates would make resolution order-dependent.","triggerScenarios":"Calling skillref.New with a mappings slice containing two Mapping entries whose From.String() values are identical (e.g. the same skill remapped twice, or the same exact source path declared in two overlay entries).","commonSituations":"Merging overlay fragments from multiple config layers that each remap the same skill; copy-pasted remap entries in a config file; automated config generation that appends instead of replacing entries.","solutions":["Remove or merge the duplicate mapping so each source reference appears exactly once.","If entries come from multiple config layers, deduplicate by From.String() before constructing the Resolver, keeping the intended final target.","De-duplicate programmatically: build a map keyed by From.String() and pass its values to skillref.New."],"exampleFix":"// before\nmappings := []skillref.Mapping{{From: a, To: b}, {From: a, To: c}} // duplicate source\n// after: keep last-wins dedup\nbySource := map[string]skillref.Mapping{}\nfor _, m := range raw { bySource[m.From.String()] = m }\nuniq := make([]skillref.Mapping, 0, len(bySource))\nfor _, m := range bySource { uniq = append(uniq, m) }","handlingStrategy":"validation","validationCode":"func dedupeMappings(ms []skillref.Mapping) []skillref.Mapping {\n    seen := map[string]bool{}\n    out := make([]skillref.Mapping, 0, len(ms))\n    for _, m := range ms {\n        k := m.From.String()\n        if seen[k] { continue }\n        seen[k] = true\n        out = append(out, m)\n    }\n    return out\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate overlay entries by source reference before calling skillref.New.","When merging config layers, replace entries by key instead of appending.","Add a config lint that fails on duplicate remap sources."],"tags":["go","validation","config","duplicate-key"],"backgroundTag":"duplicate-config-key","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"}