larksuite/cli · error · LarkCliError
lark-cli returned a non-object JSON payload
Error message
lark-cli returned a non-object JSON payload
What it means
run_sheets() requires the lark-cli response to be a JSON object (dict) acting as an envelope. If the stdout parses as valid JSON but is a list, string, number, bool, or null instead of an object, this error is raised. Like error 31, it signals a contract violation between the lark-cli binary and this helper: exit code 0 and parseable JSON, but the wrong top-level shape.
Source
Thrown at skills/lark-sheets/scripts/lark_sheet_read_cli.py:93
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
def envelope_data(envelope: dict[str, Any]) -> dict[str, Any]:
data = envelope.get("data")
return data if isinstance(data, dict) else envelope
def emit_success(action: str, data: dict[str, Any], warnings: list[str] | None = None) -> None:
print(
json.dumps(
{
"ok": True,
"engine": "lark",
"action": action,
"data": data,
"warnings": warnings or [],
},View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Print the raw stdout (run the command from LarkCliError.cmd manually) to see the actual JSON shape being returned.
- Check `lark-cli --version` and align with the version this helper expects; upgrade or reinstall lark-cli to restore the envelope contract.
- Ensure no mock/stub/wrapper lark-cli is on PATH intercepting the call.
- If you own the pipeline, wrap raw payloads in an envelope before returning, or upgrade the helper to match the new contract.
Example fix
# before: raw payload breaks the envelope contract (non-object JSON)
print(json.dumps(rows))
# after: emit the expected envelope object
print(json.dumps({"ok": True, "data": {"rows": rows}})) Defensive patterns
Strategy: type-guard
Validate before calling
import subprocess, json
out = subprocess.run(["lark-cli", "sheets", "info", "--url", url], capture_output=True, text=True)
parsed = json.loads(out.stdout)
if not isinstance(parsed, dict) or "ok" not in parsed:
raise RuntimeError(f"unexpected lark-cli payload shape: {type(parsed).__name__}") Type guard
def is_envelope(payload: object) -> bool:
return isinstance(payload, dict) and isinstance(payload.get("ok"), bool) Try / catch
from lark_sheet_read_cli import LarkCliError
try:
envelope = run_sheets("read", url=url)
except LarkCliError as exc:
if str(exc) == "lark-cli returned a non-object JSON payload":
print("lark-cli output contract changed; verify lark-cli version")
raise Prevention
- Check `lark-cli --version` against the version the helper was written for before upgrades.
- Ensure no stub/mock lark-cli binary shadows the real one on PATH.
- Validate one representative call returns {"ok": ...} envelope shape during environment setup.
- When updating lark-cli, re-run smoke tests that assert the envelope schema.
When it happens
Trigger: completed.returncode == 0, json.loads(completed.stdout) succeeds, but the result is not a dict — e.g. lark-cli emits a bare JSON array of rows, a quoted string, or `null`; typically caused by an incompatible or modified lark-cli version whose output schema differs from the envelope format (`{"ok": true, "data": ...}`).
Common situations: A downgraded/patched lark-cli that returns raw result arrays instead of envelopes; a mock or stub binary installed for testing that prints plain JSON; scripting a different CLI under the same name; future lark-cli versions changing the output contract.
Related errors
- lark-cli stdout was not JSON: {snippet}
- skills state is unreadable
- parse base schema for field overrides: %w
- serialize schema with field overrides: %w
- marshal key %q: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/c003f2beabd4ca8e.
Report an issue: GitHub.