Every code the API returns in {"detail"}, its status, and what it means.
The API always answers errors as {"detail": "<code>"}. The clients translate the code into the user’s
language; the English text the database adds after the code stays in the logs. A new code needs a translation in
both msaving/web/src/i18n/vi.json and en.json.
From the database
Raised inside Postgres as "<code>: developer text" and mapped in msaving/backend/app/api/errors.py.
Code
Status
Meaning
owner_required
409
A book must keep at least one owner
currency_locked
409
The account has transactions, so its currency can’t change
no_rate
409
No exchange rate to convert (changing a book’s currency with budgets)
txn_shape
422
Entries don’t fit the transaction type
category_kind
422
Wrong category kind for this transaction (transfer categories only on transfers)
budget_expense_only
422
Budgets only on expense categories
invalid_timezone
422
A timezone this database doesn’t know
setup_invalid
403
Wrong setup code, or the server already has its admin
invite_required
403
Invite-only server, no invite given
invite_invalid
403
The invite is wrong, used, revoked or expired
reset_invalid
403
The reset link is wrong, used or expired
admin_only
403
Only the server’s admin can do this
admin_self
409
The admin can’t disable their own account
not_found
404
No such user (admin tools)
From unique constraints
Code
Status
Meaning
username_taken
409
Username in use
name_taken
409
An account or person with that name exists in the book
budget_exists
409
One budget per category and period
conflict
409
Stale version, or an id already used
From the API
Code
Status
Meaning
not_signed_in
401
Missing, unknown, expired or ended session, or a disabled account
invalid_credentials
401
Wrong username or password (the same for both)
code_required
401
Two-factor is on: send the code
invalid_code
401 / 422
Wrong two-factor or recovery code
forbidden
403
Not allowed (includes RLS refusals)
origin_not_allowed
403
A browser on another address than this server
not_found
404
Doesn’t exist or not visible to this user
has_subcategories
409
Delete or move sub-categories first
cannot_invite
409
No user with that username, or they’re already in the book (the same answer for both)