# `step.store_required`

An action makes several changing calls but writes no database, and the app names no database to keep the record of its calls in.

Area 12, [Background work](/docs/jobs-and-events.md); not declinable; the next step is usually the human's.

## Why Jadpo refuses it

A changing call, such as a provider operation with `changes: true` or a
store's `put`, takes effect as soon as it is made. When an action makes
several, Jadpo records each one before it goes out and its answer when it
comes, so a retry replays the answered calls instead of sending them
again. That record is kept in a database, beside the outbox of the one
the action writes. An action that writes none has nowhere to keep it,
and Jadpo won't choose a database for it: `events: { store: }` names
the one.

## What it looks like

domains/bakery/actions/file_prices.jadpo, in a bakery app whose only
connection is `sheets`, a folder of files:








```jadpo
use app { sheets }
use bakery/failures { SheetNotKept }
use bakery/events { PricesChanged }

/// Keeps a supplier's new prices as a sheet, then a copy for the
/// accountant.
action file_prices(event: PricesChanged) fails SheetNotKept -> Unit {
    var sheet: File = attempt sheets.put(encoding.to_utf8(event.price_list), FileType.csv) {
        storage_full: SheetNotKept
    }
    var invoice_copy: File = attempt sheets.put(encoding.to_utf8(event.price_list), FileType.csv) {
        storage_full: SheetNotKept
    }
    assert sheet != invoice_copy
}
```

```text
error: `file_prices` makes 2 changing calls but writes no store to keep their record in
 --> domains/bakery/actions/file_prices.jadpo:8:31
  |
8 |     var sheet: File = attempt sheets.put(encoding.to_utf8(event.price_list), FileType.csv) {
  |                               ^^^^^^^^^^ no store for the record
  reason: Each changing call is recorded before it goes out, beside the outbox of the store its action writes, so a retry can replay it; `file_prices` writes no store, itself or through what it calls, and `app.jadpo` names none with `events: { store: }`.
  next: Add `events: { store: main }` to `application { }` in `app.jadpo` (human)
  rule: step.store_required
  help: https://jadpo.dev/docs/errors/step.store_required

check failed: 1 error, 7 files
```

`(human)` at the end of the `next:` line tells your coding agent to stop
and ask you which fix you want, because the choice is yours to make: it
decides which database keeps the record of these calls, and the events
of every action that writes none.

## How to fix it

**If a database should keep the record**, connect it and name it in
`events: { store: }` in `app.jadpo`, with its address as a setting in
`config.jadpo`. Here the database is a new one, `main`:

```jadpo
        main: {
            driver: Driver.postgres
            url: config.main_url
        }
    events: {
        store: main
    }
```









Each of `file_prices`'s two `sheets.put` calls is now recorded in `main`
before it goes out, and its answer after it. When the delivery is tried
again, the answered calls are replayed rather than sent again, and the
record is deleted when the action commits.

An action that writes a database keeps its record in that one instead,
so it never needs `events: { store: }`.

## Related

- [The record](/docs/several-changing-calls-in-one-action.md#the-record)
- [Several changing calls in one action](/docs/several-changing-calls-in-one-action.md)
- [How the record is kept](/docs/several-changing-calls-in-one-action.md#how-the-record-is-kept)
- [Where the event is kept](/docs/emitting-an-event.md#where-the-event-is-kept)
