larksuite/cli · error · ValueError

annotated_csv did not parse into the rows the server reporte

Error message

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.

What it means

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.

Source

Thrown at skills/lark-sheets/scripts/lark_detect_subtables.py:107

                current_row_number = int(match.group(1))
                current_lines = [match.group(2)]
            elif current_lines is not None:
                current_lines.append(line)
        if current_lines is not None and current_row_number is not None:
            records.append("\n".join(current_lines))
            row_numbers.append(current_row_number)

        # Cross-check against the row numbers the server itself reported.
        # _inside_quoted_field decides whether a "[row=N]" line starts a new
        # record or is content inside an open quoted field; when the payload's
        # quoting is malformed (a lone unescaped quote in a cell), that call
        # goes the wrong way and every following line is swallowed into the
        # previous cell — the rows simply vanish, and everything downstream
        # (data_range, last data row, column profiles) is quietly computed from
        # a short grid. row_indices is authoritative and already in hand, so
        # refuse rather than profile a grid that does not match it.
        if has_authoritative_rows and row_numbers != [int(r) for r in row_indices]:
            raise ValueError(
                "annotated_csv did not parse into the rows the server reported "
                f"(parsed {len(row_numbers)} rows {row_numbers[:5]}…, expected "
                f"{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."
            )

        for record in records:
            parsed = next(csv.reader([record]))
            values.append(parsed)
            max_cols = max(max_cols, len(parsed))
    else:
        reader = csv.reader(io.StringIO(text or ""))
        fallback_start = 1
        if source_range:
            fallback_start = parse_range(
                source_range,
                max_row=1_048_576,

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the resultDetail text after 'suite archive install failed:' — it contains the runner's actual error; fix that underlying cause first.
  2. Check network connectivity/proxy settings if the archive is fetched remotely, then retry the sync.
  3. Delete any cached/partially extracted suite archive and retry to rule out corruption.
  4. Verify free disk space in the staging location if extraction fails midway.

Example fix

// before: retrying blindly with no network
lark-cli skills update --layout suite
// after: verify connectivity and read the detail, then retry
curl -I https://open.feishu.cn && lark-cli skills update --layout suite
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: can we reach the archive source?
if err := probeURL(source); err != nil {
    return fmt.Errorf("suite source unreachable: %w", err)
}

Try / catch

if err := syncLayout(...); err != nil && strings.Contains(err.Error(), "suite archive install failed") {
    detail := strings.TrimPrefix(err.Error(), "suite archive install failed: ")
    // inspect detail for root cause; retry with backoff on transient network errors
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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