SpendlyCLI Docs

Troubleshooting

Fix setup problems, understand errors, and find your next step.

Command not found

Check whether your terminal can find the CLI:

command -v spendly
npm prefix --global

If it isn't installed, follow Quick start. If it is installed, make sure the bin folder under the printed npm prefix is on your PATH, then open a new terminal. An AI agent needs the CLI available in its own terminal environment too.

spendly@0.1.2 is published. If npm reports that it is missing, check the exact version against the public npm registry:

npm view spendly@0.1.2 version --registry=https://registry.npmjs.org/

If this prints 0.1.2, retry the pinned installation from that same registry:

npm install --global spendly@0.1.2 --registry=https://registry.npmjs.org/

If the lookup or installation still fails, use npm's error code to check your network, proxy, or registry authentication settings. Report the error code and redacted message through GitHub issues if the problem persists.

The shell runs words from the output as commands

Copy only the command inside a fenced command block. Do not type Markdown backticks around it: in zsh and similar shells, backticks execute their contents as command substitution. Labels printed by Spendly such as Changes, PREVIEW ONLY, or Next are output, not commands to paste into the shell.

Sign-in and storage

spendly auth status
spendly auth login

If the browser doesn't open:

spendly auth login --no-browser

Open the displayed URL on the same computer. ACCOUNT_SETUP_REQUIRED means you need to open Spendly Web once while signed in and complete setup.

Credentials normally use your operating system's credential store. For KEYCHAIN_UNAVAILABLE, restore access to that store. If you choose file storage, spendly --allow-file-storage auth login uses a plaintext local file instead. Use that fallback only on a computer and user account you control. Never share the sign-in URL, tokens, credential files, environment variables, or request headers. Authorization expires after at most 30 days and then requires browser sign-in again.

To sign out:

spendly auth logout

A name matches more than one record

List the accounts, categories, or tags and use the intended record's ID instead. Account commands accept an ID in place of a name. Expense options include --account-id, --category-id, and --tag-id. Human terminal users can add --interactive to choose from stable-ID-backed labels instead.

Interactive input is unavailable

Guided prompts require a real terminal for both input and prompt output. They are intentionally disabled for redirected or piped execution and cannot be combined with --json, --non-interactive, or --agent. Use explicit flags for those modes. Press Escape or Ctrl-C to cancel a guided command without a write. Add --accessible or set ACCESSIBLE=1 for static numbered prompts that do not redraw earlier terminal lines.

A record changed or a category doesn't fit

A revision conflict means the record changed since it was read. Fetch it again, check the current values, and retry the change using the latest revision if you supplied one.

CATEGORY_CYCLE_MISMATCH means the category belongs to another cycle. Choose a category from the expense's new cycle or use --clear-category on the edit. An archived account must be reactivated before it can receive new activity.

A cycle cannot be saved or deleted

CYCLE_OVERLAP means its dates intersect another owned cycle. Ends are exclusive, so adjacent cycles may share an end/start boundary. CYCLE_REVISION_CONFLICT requires a fresh cycles get CYCLE_ID and preview. CYCLE_COPY_CONFLICT (exit 5) means the effective category copy no longer matches the reviewed snapshot. Stop, obtain a fresh creation dry run, and get approval before a new commit; do not blindly retry or change the payload. Capture data.copySnapshot and commit with --if-copy-snapshot HASH using identical source, selection, and plan inputs. The hash must be 64 lowercase hex characters; the flag requires --copy-from-cycle-id and cannot accompany --dry-run. An invalid or missing backend copy guard is INVALID_INPUT (exit 2); ordinary CLI copying writes obtain the guard automatically. CYCLE_HAS_EXPENSES blocks deletion while any expense is linked to that cycle; removing categories or changing dates does not remove those links. Deletion also removes every category. Invalid/expired confirmation tokens require a new cycles delete CYCLE_ID --dry-run, reviewed before committing.

A connection failed while saving

The change may have saved even if the response was lost. Check the affected expense, cycle, or account history first. Write commands do not retry automatically. Only when the user explicitly asks to recover the intended write, repeat the identical command with its original --idempotency-key so it cannot create a second change. If you don't have the key, or the retry is also uncertain, stop and report the outcome as unknown rather than attempting another write.

For cycle writes, human errors also print the resolved inputs and generated key. If you explicitly choose to recover that same write, supply its original inputs, copy snapshot, revision, token, and key with --non-interactive; keep the original agent mode. An explicit --if-copy-snapshot makes no new preview/source read in this mode. Backend idempotency returns a saved result before checking the guard, even if the copy source later changed or was deleted. This also avoids human preview/read checks that would otherwise prevent replaying an edit with an old revision or a deletion of an already-removed cycle. A fresh intent after a conflict instead needs a fresh read, preview, and key.

An idempotency conflict means a key was used with different input. Check the original action; a new action needs a new key. For an expired deletion token, run the deletion preview again to get a current one.

Update or remove the CLI

Update the CLI and skill with:

npm install --global spendly
npx skills update spendly --global

Check spendly --version after every update. To reinstall the exact initial version, use npm install --global spendly@0.1.2. Spendly supports Node.js 22 or newer on the platforms listed in Quick start and will remain below 1.0.0 until real usage proves its CLI contract is stable.

To remove the CLI:

spendly auth logout
npm uninstall --global spendly

Get help

spendly --help
spendly expenses add --help
spendly accounts transfer --help

--debug adds redacted diagnostic details on stderr if you need to investigate an error. Review diagnostic output before sharing it in a bug report. Use GitHub issues for ordinary problems. Report suspected vulnerabilities through private vulnerability reporting, never a public issue. Do not include tokens, OAuth URLs, headers, credential files, environment values, or personal financial output.

On this page