larksuite/cli · error · LarkCliError

lark-cli not found

Error message

lark-cli not found

What it means

run_sheets() shells out to the `lark-cli` executable via subprocess. When the OS raises FileNotFoundError because `lark-cli` is not on PATH, the library wraps it as LarkCliError("lark-cli not found", cmd=cmd) so callers get a typed error naming the attempted command instead of a raw subprocess exception.

Source

Thrown at skills/lark-sheets/scripts/lark_sheet_read_cli.py:76

    cmd = ["lark-cli", "sheets", shortcut]
    _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

  1. Install lark-cli (make build or its release install) and ensure the binary is on PATH.
  2. Verify with `which lark-cli` / `lark-cli --version` in the same environment that runs the Python script.
  3. If PATH differs (cron, systemd, IDE), extend os.environ['PATH'] in the script or invoke lark-cli by absolute path.
  4. Activate the correct virtualenv/shell before running the script.

Example fix

// before
run_sheets("read", url=url)  # LarkCliError: lark-cli not found

// after
import os, shutil
if shutil.which("lark-cli") is None:
    os.environ["PATH"] += os.pathsep + "/usr/local/bin"
run_sheets("read", url=url)
Defensive patterns

Strategy: validation

Validate before calling

import shutil
if shutil.which("lark-cli") is None:
    raise SystemExit("lark-cli is not installed or not on PATH; install it or fix PATH")

Type guard

def lark_cli_available() -> bool:
    import shutil
    return shutil.which("lark-cli") is not None

Try / catch

try:
    data = run_sheets(shortcut, url=url)
except LarkCliError as e:
    if "lark-cli not found" in str(e):
        raise SystemExit("Install lark-cli and ensure it is on PATH") from e
    raise

Prevention

When it happens

Trigger: Any run_sheets()-based call (read, check_sheet, inspect_workbook, detect_subtables, profile_table) when the lark-cli binary is not installed or not in the PATH of the Python process.

Common situations: Fresh machine or CI container where lark-cli was never installed; running the script from cron/IDE/venv whose PATH differs from the shell; lark-cli installed under a different name or via a build that did not put the binary on PATH.

Related errors


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