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 --globalIf 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 loginIf the browser doesn't open:
spendly auth login --no-browserOpen 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 logoutA 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 --globalCheck 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 spendlyGet 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.