{"record":{"id":"68396eda46c1f389","repo":"larksuite/cli","slug":"annotated-csv-did-not-parse-into-the-rows-the-serv","errorCode":null,"errorMessage":"annotated_csv did not parse into the rows the server reported (parsed {len(row_numbers)} rows {row_numbers[:5]}…, expected {len(row_indices)} rows {list(row_indices)[:5]}…) — most likely an unbalanced quote in a cell. Re-read a narrower --range, or use +cells-get for this region instead of the CSV path.","messagePattern":"annotated_csv did not parse into the rows the server reported \\(parsed (.+?) rows (.+?)…, expected (.+?) rows (.+?)…\\) — most likely an unbalanced quote in a cell\\. Re-read a narrower --range, or use \\+cells-get for this region instead of the CSV path\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/lark-sheets/scripts/lark_detect_subtables.py","lineNumber":107,"sourceCode":"                current_row_number = int(match.group(1))\n                current_lines = [match.group(2)]\n            elif current_lines is not None:\n                current_lines.append(line)\n        if current_lines is not None and current_row_number is not None:\n            records.append(\"\\n\".join(current_lines))\n            row_numbers.append(current_row_number)\n\n        # Cross-check against the row numbers the server itself reported.\n        # _inside_quoted_field decides whether a \"[row=N]\" line starts a new\n        # record or is content inside an open quoted field; when the payload's\n        # quoting is malformed (a lone unescaped quote in a cell), that call\n        # goes the wrong way and every following line is swallowed into the\n        # previous cell — the rows simply vanish, and everything downstream\n        # (data_range, last data row, column profiles) is quietly computed from\n        # a short grid. row_indices is authoritative and already in hand, so\n        # refuse rather than profile a grid that does not match it.\n        if has_authoritative_rows and row_numbers != [int(r) for r in row_indices]:\n            raise ValueError(\n                \"annotated_csv did not parse into the rows the server reported \"\n                f\"(parsed {len(row_numbers)} rows {row_numbers[:5]}…, expected \"\n                f\"{len(row_indices)} rows {list(row_indices)[:5]}…) — most likely \"\n                \"an unbalanced quote in a cell. Re-read a narrower --range, or use \"\n                \"+cells-get for this region instead of the CSV path.\"\n            )\n\n        for record in records:\n            parsed = next(csv.reader([record]))\n            values.append(parsed)\n            max_cols = max(max_cols, len(parsed))\n    else:\n        reader = csv.reader(io.StringIO(text or \"\"))\n        fallback_start = 1\n        if source_range:\n            fallback_start = parse_range(\n                source_range,\n                max_row=1_048_576,","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/skills/lark-sheets/scripts/lark_detect_subtables.py#L89-L125","documentation":"syncSuite stages the suite archive into the staging root via runner.StageSuite. If the runner returns nil or a result with Err set, the sync aborts with this message containing resultDetail(stageResult) — the runner's own diagnostic. The root cause lives in that detail string.","triggerScenarios":"Running a skills sync in suite mode where StageSuite fails: the source archive is missing/corrupt, the download or unpack step errors, network failure fetching the suite archive, or the runner's underlying command exits non-zero.","commonSituations":"Network outages or proxies blocking the skills archive download; a partial/corrupt cached archive; disk full during extraction; a plugin/mocked SkillsRunner in tests returning an error result.","solutions":["Read the resultDetail text after 'suite archive install failed:' — it contains the runner's actual error; fix that underlying cause first.","Check network connectivity/proxy settings if the archive is fetched remotely, then retry the sync.","Delete any cached/partially extracted suite archive and retry to rule out corruption.","Verify free disk space in the staging location if extraction fails midway."],"exampleFix":"// before: retrying blindly with no network\nlark-cli skills update --layout suite\n// after: verify connectivity and read the detail, then retry\ncurl -I https://open.feishu.cn && lark-cli skills update --layout suite","handlingStrategy":"retry","validationCode":"// Pre-flight: can we reach the archive source?\nif err := probeURL(source); err != nil {\n    return fmt.Errorf(\"suite source unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := syncLayout(...); err != nil && strings.Contains(err.Error(), \"suite archive install failed\") {\n    detail := strings.TrimPrefix(err.Error(), \"suite archive install failed: \")\n    // inspect detail for root cause; retry with backoff on transient network errors\n}","preventionTips":["Check network/proxy connectivity before suite-mode syncs in CI.","Clear cached or partially extracted archives after failed syncs.","Read the resultDetail suffix first — it names the underlying runner error."],"tags":["go","network","archive","skills-sync"],"backgroundTag":"archive-staging-failed","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"}