Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 1 Nov 2026. What's built · Install 0.2.0
jadpo
Reference: Personal data

Personal data · rule

data.retention_held

On this page

An entity's retention: would delete records that a restricted reference keeps from being deleted.

Area 15, Personal data; not declinable; the next step is usually the human's.

Why Jadpo refuses it

A retention: on an entity deletes each record when its time is up, with everything that cascades from it. A reference marked OnDelete.restricted says the opposite: the record it points at can't be deleted while it does. Here an invoice is kept for six years, but a payment refers to it with a restricted reference, so every invoice that was paid would stay past its retention, and the app would never know.

Jadpo won't choose for you: what happens to a payment when its invoice goes is a decision about your records.

What it looks like

main.jadpo:

example
config {    invoice_retention: Duration {        default: 2192d    }}entity Invoice {    id: Uuid    issued_at: Instant {        generated: Generated.on_create    }    retention: {        after: config.invoice_retention        since: issued_at    }}entity Payment {    id: Uuid    invoice_id: Invoice.id {        on_delete: OnDelete.restricted    }}
jadpo checkcheck failed: 1 error, 1 file

error Invoice's retention can't delete an invoice a Payment holds

--> main.jadpo:13:5

   |13 |     retention: {   |     ^^^^^^^^^ deletes each invoice when its time is up21 |     invoice_id: Invoice.id {   |     ---------- `Payment.invoice_id` is `OnDelete.restricted`
reason
Retention deletes each record when its time is up, with what cascades from it. Payment.invoice_id is OnDelete.restricted, which refuses to delete the record it refers to, so an invoice it holds would be kept past its retention.
next
Say what deleting the record does to Payment: OnDelete.cascade on invoice_id deletes it too, and OnDelete.cleared keeps it without the reference (human)
rule
data.retention_held
help
https://jadpo.dev/docs/errors/data.retention_held

(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 whether a payment is kept once its invoice is deleted.

A reference that holds the record through a cascade is refused the same way: if deleting an invoice deleted its lines, a refund holding a line with a restricted reference would keep the invoice too.

How to fix it

The question is what should happen to a payment when its invoice's time is up.

If the payment goes with its invoice, make the reference cascade:

example
entity Payment {    id: Uuid    invoice_id: Invoice.id {        on_delete: OnDelete.cascade    }}

An invoice past its retention is now deleted with its payments. Ordinary code deleting an invoice deletes its payments too.

If the payment is kept without its invoice, make the reference one that can be none and is cleared:

example
entity Payment {    id: Uuid    invoice_id: Invoice.id? {        on_delete: OnDelete.cleared    }}

An invoice past its retention is now deleted, and each of its payments stays with invoice_id set to none.

Markdown for agents: /docs/errors/data.retention_held.md.Built from Jadpo main at e00e61f.