{"record":{"id":"c16dc49790040eb4","repo":"larksuite/cli","slug":"lark-cli-timed-out-after-timeout-s","errorCode":null,"errorMessage":"lark-cli timed out after {timeout}s","messagePattern":"lark-cli timed out after (.+?)s","errorType":"exception","errorClass":"LarkCliError","httpStatus":null,"severity":"error","filePath":"skills/lark-sheets/scripts/lark_sheet_read_cli.py","lineNumber":78,"sourceCode":"    _append_flag(cmd, \"url\", url)\n    _append_flag(cmd, \"spreadsheet_token\", spreadsheet_token)\n    _append_flag(cmd, \"sheet_id\", sheet_id)\n    _append_flag(cmd, \"sheet_name\", sheet_name)\n    for key, value in (flags or {}).items():\n        _append_flag(cmd, key, value)\n\n    try:\n        completed = subprocess.run(\n            cmd,\n            capture_output=True,\n            text=True,\n            timeout=timeout,\n            check=False,\n        )\n    except FileNotFoundError as exc:\n        raise LarkCliError(\"lark-cli not found\", cmd=cmd) from exc\n    except subprocess.TimeoutExpired as exc:\n        raise LarkCliError(f\"lark-cli timed out after {timeout}s\", cmd=cmd) from exc\n\n    if completed.returncode != 0:\n        detail = (completed.stderr or completed.stdout or \"\").strip()\n        raise LarkCliError(detail or f\"lark-cli exited with {completed.returncode}\", cmd=cmd)\n\n    try:\n        envelope = json.loads(completed.stdout)\n    except json.JSONDecodeError as exc:\n        snippet = completed.stdout[:500].replace(\"\\n\", \"\\\\n\")\n        raise LarkCliError(f\"lark-cli stdout was not JSON: {snippet}\", cmd=cmd) from exc\n\n    if isinstance(envelope, dict) and envelope.get(\"ok\") is False:\n        raise LarkCliError(json.dumps(envelope, ensure_ascii=False), cmd=cmd)\n    if not isinstance(envelope, dict):\n        raise LarkCliError(\"lark-cli returned a non-object JSON payload\", cmd=cmd)\n    return envelope\n\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/skills/lark-sheets/scripts/lark_sheet_read_cli.py#L60-L96","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nresult = run_sheets(\"read\", url=huge_sheet_url)  # default 60s timeout\n\n// after\nresult = run_sheets(\"read\", url=huge_sheet_url, timeout=300)","handlingStrategy":"retry","validationCode":"# size the timeout to the request: large sheets / slow links need more headroom\nTIMEOUT = 300  # seconds, instead of the 60s default","typeGuard":"def timeout_is_sufficient(rows_estimate: int, timeout: int) -> bool:\n    return timeout >= max(60, rows_estimate // 100)  # rough sizing heuristic","tryCatchPattern":"import time\nfor attempt in range(3):\n    try:\n        return run_sheets(shortcut, url=url, timeout=300)\n    except LarkCliError as e:\n        if \"timed out\" in str(e) and attempt < 2:\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["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."],"tags":["python","timeout","network","subprocess"],"backgroundTag":"process-timeout","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"}