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
- 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.
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
- 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.
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
- --max-sheets must be at least 1
- suite skills sync failed: %s
- +csv-get truncated the scan range at {actual_range}; narrow
- Device authorization failed: read body: %v
- failed to read response body in security transport: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/68396eda46c1f389.
Report an issue: GitHub.