# Bank import and close refusal codes

> The finance engine refuses before it writes. Each refusal returns a code and the figures that explain it, so an agent can tell the operator what to do rather than what went wrong. None of these leaves a half-written state: a refused import writes zero rows, a refused close writes no row, a refused split writes nothing.

URL: https://biloh.com.au/docs/reference/bank-import-and-close-refusal-codes
Category: Reference | Audience: agent | Updated: 2026-09-18

## Bank feed

| Code | Tool | Meaning | Comes with | Next step |
| --- | --- | --- | --- | --- |
| `wrong_account_or_gap` | `import_bank_csv` | The file's implied opening balance does not chain onto the account | Expected and actual balances; zero rows written | Wrong file for this account, or a missing window: export the right days |
| `override_reason_required` | `import_bank_csv` | `override_chain_gap` was set with an empty reason | Nothing imported | Give a reason; the override is audit-logged |
| `identifier_not_masked` | `create_bank_account` | A full account number or BSB was supplied | Nothing stored | Supply the last four digits only |
| `bank_completeness_failed` | `run_period_close`, `run_month_end_close` | A line in the range fails to tie by running balance | First break's date and the gap in cents; no row written | Import the missing window, or sign off over the gap with a reason |
| `needs_variance_reason` | `run_period_close` | A peer total was passed and differs from Biloh's received figure | `variance_cents`, `received_cents` | Explain the variance in `variance_reason` and retry |

## Money in

| Code | Tool | Meaning | Next step |
| --- | --- | --- | --- |
| `already_matched` | `match_bank_credit_to_invoice` | This deposit has already paid an invoice; the payment is keyed to the deposit so it can never pay twice | Nothing to do, or unmatch first if the earlier match was wrong |
| `already_paid` (warning) | `get_reconciliation_suggestions`, `triage_bank_feed` | The candidate invoice is settled and is offered only because the bank text names it | Usually `link_bank_credit_to_existing_payment` |
| `amount_mismatch` (warning) | same | The deposit and the invoice differ in amount | A part payment, split or fee: match knowingly, or decide otherwise |

## Money out

| Code | Tool | Meaning | Next step |
| --- | --- | --- | --- |
| `split_total_mismatch` | `split_bank_transaction` | The splits do not sum to the line; the message names the gap in cents | Correct the amounts |
| `gst_exceeds_one_eleventh` | `split_bank_transaction` | A split claims more GST than one eleventh of its own amount | Correct the GST |
| `gst_requires_evidence` | `split_bank_transaction` | A split claims GST with no document and no attestation | Attach the receipt or state where the paper is |
| `invalid_expense_payload` | `split_bank_transaction` | An impossible GST and treatment pair | Correct the pair |
| `already_split`, `bank_txn_already_matched`, `split_requires_debit`, `category_not_found` | `split_bank_transaction` | State refusals | Unsplit or unmatch first; use a debit; use a listed category |
| `bank_line_not_debit` | `confirm_shoebox_pairing` | A receipt substantiates money going out, not in | Pair against a debit |
| `already_exited` | `confirm_shoebox_pairing` | The receipt already left as a cash expense | Unpick that expense first if it was wrong |
| GST on an unregistered contractor | `record_bill` and settlement tools | The contractor is not GST-registered and the bill claims GST | Governed by `finance.ap.unregistered_gst_enforcement`; correct the bill |
| Out-of-gate settlement | `settle_bill_with_bank_debit` | The linked client invoice is unpaid | Governed by `finance.ap.out_of_gate_settlement`: warn or refuse |
| Paid date in a closed period | settlement tools | The debit's value date falls inside a closed period | Reopen the period with a reason first |

## Assets

| Code | Tool | Meaning | Next step |
| --- | --- | --- | --- |
| Instant write-off above threshold | `create_asset` | The cost exceeds `finance.assets.instant_writeoff_threshold`; the refusal names the threshold | Choose diminishing value or prime cost with an effective life |
| Debit already minted an asset | `create_asset` | One debit mints one asset | Split the line first if it bought two things |

## Obligations

| Code | Tool | Meaning | Next step |
| --- | --- | --- | --- |
| Receipt required | `mark_obligation_lodged` | No lodgement receipt document was named | Record the receipt in the evidence layer, then lodge with its id |

## Periods

| Code | Tool | Meaning | Next step |
| --- | --- | --- | --- |
| Not closed | `reopen_period` | The period was never closed | Nothing to reopen; make the change |
| `open_child_months` (warning) | `run_period_close` | A quarter or FY was closed over open months | Close the months, then re-close the parent |
| `stale` (state) | `get_period_ladder` | A child was reopened after this period closed | Re-close the parent |

## Cross-cutting

| Code | Where | Meaning |
| --- | --- | --- |
| `expected_tenant_mismatch` | any tool | The `expected_tenant` assertion did not match the connection's tenant; nothing ran. See [write safety](/docs/reference/write-safety-expected-tenant) |
| `upgrade_required` | tier-gated tools | The capability is not in this business's plan |

## Related

- [The balance chain](/docs/concepts/the-balance-chain)
- [Finance MCP tools](/docs/reference/finance-mcp-tools)
