# When a call fails

Errors come back as `{error, code, hint}`. The `hint` is written for you and
usually contains the exact fix — read it before retrying.

## Error codes

### `unknown_operation`
The operation id does not exist. The hint suggests near matches. Operation ids
are always `provider.resource.verb` (`brreg.roller.get`, not `brreg_get_roles`
or `get_company_roles`). **Do not invent ids** — run `norsk_search`.

### `unknown_param`
You passed a parameter this operation does not have. The hint lists the valid
ones. Usually an English guess at a Norwegian name (`orgnummer` for `orgnr`,
`name` for `navn`, `municipality` for `kommunenummer`).

### `missing_param`
A required parameter is absent. The hint includes a complete worked example call
you can adapt.

### `bad_param`
Right name, wrong type or an invalid enum value. The hint states what was
expected.

### `invalid_orgnr`
Nine digits that fail the mod-11 checksum. This is a **typo, not a missing
company** — no amount of retrying will fix it. Re-read the number, or search by
name instead.

### `not_found` (404)
The upstream register has no such record. Real causes, in order of likelihood:
- The org number belongs to an **underenhet** and you called a hovedenhet
  operation (or the reverse).
- The entity was deregistered.
- The identifier is valid but for a different register.

Try `norsk_resolve` on whatever the user originally said.

### `rate_limited` (429)
Retried three times with backoff already. Wait a few seconds. If you are
looping over many entities, add a delay or reduce the number of calls — screening
50 companies one call at a time is what triggers this.

### `upstream_error` (5xx)
The provider is having problems. Not your parameters. Retrying later may work;
retrying immediately will not.

There is one special case: **"returned HTML, not JSON"** means an upstream
endpoint moved and the catalog entry is stale. That is a server bug, not
something you can fix by changing parameters — report the operation id.

### `network_error`
Timeout or DNS failure reaching the provider.

### `parse_error`
The provider returned something unparseable. Server-side problem; report it.

## Failures that are not errors

**An empty result array is a valid answer.** Distinguish clearly:

| Situation | What to say |
|---|---|
| `brreg.regnskap.get` returns `[]` | "This entity does not file public accounts" |
| `brreg.enhet.search` returns `[]` | "No Norwegian company matches that name" |
| `brreg.roller.get` returns `[]` | "No roles are currently registered" |
| `norsk_search` finds nothing useful | "This server does not cover that" |

None of these are tool failures. Reporting them as "I couldn't retrieve the
data" is wrong and misleads the user into thinking retrying would help.

## When search finds nothing

1. Try **Norwegian** keywords — the catalog is indexed in both languages but
   Norwegian terms are more specific (`regnskap` beats `financials`).
2. Try the intent rather than the mechanism: "who runs this company" not
   "get board endpoint".
3. Call `norsk_providers` to see what exists at all.
4. If it genuinely is not covered, **say so.** The catalog is public registers
   and a few business systems — it has no personal data, no credit scores, no
   ownership percentages, and no write operations.

## Debugging a wrong-looking answer

- Check `meta.source` — did it come from `mock:`? Those are fixtures.
- Check `meta.fetched_at` and `meta.cache`. A cached response can be up to
  24 hours old for registry data, 7 days for accounts.
- Check `meta.truncated`. A "the answer is 3" conclusion drawn from a truncated
  list of 10 out of 88 is wrong.
- For financial oddities, read the `regnskap` guide — holding companies and
  changed financial years both produce figures that look like errors but are not.
