larksuite/cli · error · LarkCliError
Pass exactly one of --url or --spreadsheet-token
Error message
Pass exactly one of --url or --spreadsheet-token
What it means
run_sheets() in lark_sheet_read_cli.py requires the caller to identify the spreadsheet in exactly one way: either a --url or a --spreadsheet-token. It checks `bool(url) == bool(spreadsheet_token)`, so providing both, or neither, is rejected with LarkCliError before the lark-cli subprocess is invoked.
Source
Thrown at skills/lark-sheets/scripts/lark_sheet_read_cli.py:55
return
if isinstance(value, bool):
cmd.append(flag if value else f"{flag}=false")
return
cmd.extend([flag, str(value)])
def run_sheets(
shortcut: str,
*,
url: str | None = None,
spreadsheet_token: str | None = None,
sheet_id: str | None = None,
sheet_name: str | None = None,
flags: dict[str, Any] | None = None,
timeout: int = 60,
) -> dict[str, Any]:
if bool(url) == bool(spreadsheet_token):
raise LarkCliError("Pass exactly one of --url or --spreadsheet-token")
if sheet_id and sheet_name:
raise LarkCliError("Pass only one of --sheet-id or --sheet-name")
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,View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Pass exactly one identifier: delete the spreadsheet_token argument if you pass url, and vice versa.
- If both are populated, extract the token from the URL (the token is the spreadsheet ID segment) and pass only that.
- If neither is set, resolve the URL/token from config, env, or the command line before calling run_sheets.
Example fix
// before
run_sheets("read", url=sheet_url, spreadsheet_token=token) # LarkCliError
// after
run_sheets("read", url=sheet_url) # exactly one identifier Defensive patterns
Strategy: validation
Validate before calling
if bool(url) == bool(spreadsheet_token):
raise SystemExit("Provide exactly one of --url or --spreadsheet-token") Type guard
def has_one_identifier(url, token) -> bool:
return bool(url) != bool(token) Try / catch
try:
data = run_sheets(shortcut, url=url, spreadsheet_token=token)
except LarkCliError as e:
if "exactly one of --url or --spreadsheet-token" in str(e):
data = run_sheets(shortcut, url=url or f"https://example.feishu.cn/sheets/{token}")
else:
raise Prevention
- Normalize input early: derive the token from the URL once, then only pass one form.
- In CLI wrappers, make --url and --spreadsheet-token a mutually exclusive group.
- Never bake a default token into config that can coexist with a user-supplied URL.
When it happens
Trigger: Calling run_sheets()/read helpers with both url and spreadsheet_token set, or with both None/empty (e.g. forgetting to pass the URL entirely).
Common situations: Config files or CLI parsing that fill in a default token while a URL is also passed; copying an example that sets url but leaving a stale spreadsheet_token in config; omitting both because the script expected an environment variable to provide one.
Related errors
- Pass only one of --sheet-id or --sheet-name
- --header-scan-rows must be at least 1
- +csv-get truncated the requested range at {source_range}; na
- lark-cli exited with {completed.returncode}
- {message}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/4a0582efa23c88e1.
Report an issue: GitHub.