larksuite/cli · error · LarkCliError
lark-cli timed out after {timeout}s
Error message
lark-cli timed out after {timeout}s What it means
run_sheets() runs lark-cli with a subprocess timeout (default 60s). If lark-cli does not finish in time, subprocess.TimeoutExpired is wrapped as LarkCliError("lark-cli timed out after {timeout}s", cmd=cmd), protecting callers from hanging indefinitely on a stuck network call.
Source
Thrown at skills/lark-sheets/scripts/lark_sheet_read_cli.py:78
_append_flag(cmd, "url", url)
_append_flag(cmd, "spreadsheet_token", spreadsheet_token)
_append_flag(cmd, "sheet_id", sheet_id)
_append_flag(cmd, "sheet_name", sheet_name)
for key, value in (flags or {}).items():
_append_flag(cmd, key, value)
try:
completed = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout,
check=False,
)
except FileNotFoundError as exc:
raise LarkCliError("lark-cli not found", cmd=cmd) from exc
except subprocess.TimeoutExpired as exc:
raise LarkCliError(f"lark-cli timed out after {timeout}s", cmd=cmd) from exc
if completed.returncode != 0:
detail = (completed.stderr or completed.stdout or "").strip()
raise LarkCliError(detail or f"lark-cli exited with {completed.returncode}", cmd=cmd)
try:
envelope = json.loads(completed.stdout)
except json.JSONDecodeError as exc:
snippet = completed.stdout[:500].replace("\n", "\\n")
raise LarkCliError(f"lark-cli stdout was not JSON: {snippet}", cmd=cmd) from exc
if isinstance(envelope, dict) and envelope.get("ok") is False:
raise LarkCliError(json.dumps(envelope, ensure_ascii=False), cmd=cmd)
if not isinstance(envelope, dict):
raise LarkCliError("lark-cli returned a non-object JSON payload", cmd=cmd)
return envelope
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Raise the timeout: call run_sheets(..., timeout=300) for large sheets or slow links.
- Narrow the request: pass a specific sheet_id/sheet_name or a smaller range so lark-cli returns less data.
- Check for pending authentication (run `lark-cli` interactively once to complete login).
- Retry on a stable connection; the timeout may be transient network latency.
Example fix
// before
result = run_sheets("read", url=huge_sheet_url) # default 60s timeout
// after
result = run_sheets("read", url=huge_sheet_url, timeout=300) Defensive patterns
Strategy: retry
Validate before calling
# size the timeout to the request: large sheets / slow links need more headroom TIMEOUT = 300 # seconds, instead of the 60s default
Type guard
def timeout_is_sufficient(rows_estimate: int, timeout: int) -> bool:
return timeout >= max(60, rows_estimate // 100) # rough sizing heuristic Try / catch
import time
for attempt in range(3):
try:
return run_sheets(shortcut, url=url, timeout=300)
except LarkCliError as e:
if "timed out" in str(e) and attempt < 2:
time.sleep(2 ** attempt)
continue
raise Prevention
- Pass an explicit generous timeout for large sheets instead of relying on the 60s default.
- Scope reads to a single sheet or range to reduce response size.
- Complete lark-cli authentication interactively first so it never blocks waiting for a prompt.
- Add bounded retry with backoff for transient network latency.
When it happens
Trigger: Reading a very large sheet or slow network where the lark-cli API call exceeds the timeout passed to run_sheets() (or the 60s default).
Common situations: Huge spreadsheets with many rows/subtables; slow or proxied corporate networks; lark-cli waiting on interactive auth it cannot prompt for in a non-TTY context; transient API latency spikes.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- lark-cli exited with {completed.returncode}
- poll network error: %w
- no hello_ack received: %w
- npm install timed out after %s
- pnpm install timed out after %s
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/c16dc49790040eb4.
Report an issue: GitHub.