Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 5 Nov 2026. What's built · Install 0.3.0
jadpo
ReferenceErrors

ErrorsReads and writes · rule

data.lifecycle_owned_field

On this page

A create, update or patch sets a field that only the entity's lifecycle may change.

Area 6, Reads and writes; not declinable; the next step is usually the agent's.

Why Jadpo refuses it

A lifecycle owns every field its transitions set and every field its initial: gives. Those fields change only through the transitions, so a record always moves between its stages as the lifecycle says: a when: is checked, and every field the transition sets changes together.

Here hide_todo sets deleted_at with a plain update. That skips the delete transition, so anything the transition adds later, such as a when: or a second field, would be skipped too.

What it looks like

main.jadpo:

example
entity Todo {    id: Uuid    deleted_at: Instant?    lifecycle: {        visible: deleted_at == none        transitions: {            delete: {                set: {                    deleted_at: clock.now                }            }        }    }}action hide_todo(todo: Todo) -> Todo {    return Todo.update(todo) {        set: {            deleted_at: clock.now        }    }}
jadpo checkcheck failed: 1 error, 1 file

error Todo.update sets deleted_at, which only Todo's lifecycle changes

--> main.jadpo:20:13

   |20 |             deleted_at: clock.now   |             ^^^^^^^^^^ owned by the lifecycle
reason
Todo's lifecycle owns deleted_at: only its transition delete changes it, so the record's stages always move as the lifecycle says.
next
Remove deleted_at, and call Todo.delete(todo) to change it (agent)
rule
data.lifecycle_owned_field
help
https://jadpo.dev/docs/errors/data.lifecycle_owned_field

(agent) at the end of the next: line means your coding agent can make the fix itself.

A create that gives a field initial: gives is refused too. Here every new story starts as a draft, and start_story tries to start one in review:

main.jadpo:

example
type HeadlineText = Text {    max_length: 120}type ReviewStage = Enum {    draft    in_review}entity Story {    id: Uuid    headline: HeadlineText    stage: ReviewStage    lifecycle: {        initial: {            stage: ReviewStage.draft        }        transitions: {            submit: {                when: stage == ReviewStage.draft                set: {                    stage: ReviewStage.in_review                }            }        }    }}action start_story(headline: Story.headline) -> Story {    return Story.create {        set: {            headline: headline            stage: ReviewStage.in_review        }    }}
jadpo checkcheck failed: 1 error, 1 file

error Story.create sets stage, which only Story's lifecycle changes

--> main.jadpo:34:13

   |34 |             stage: ReviewStage.in_review   |             ^^^^^ owned by the lifecycle
reason
Story's lifecycle owns stage: only its transition submit changes it, so the record's stages always move as the lifecycle says. A new record gets it from initial:, or none when the lifecycle gives none.
next
Remove stage here (agent)
rule
data.lifecycle_owned_field
help
https://jadpo.dev/docs/errors/data.lifecycle_owned_field

How to fix it

If the update is the stage change a transition makes, call the transition instead. Todo.delete runs the delete transition and gives nothing back:

example
action hide_todo(todo: Todo) -> Unit {    Todo.delete(todo)}

Hiding a todo now goes through delete, so it sets deleted_at exactly as the lifecycle says, and the todo drops out of every read.

If a create gives a field initial: gives, remove that line:

example
    return Story.create {        set: {            headline: headline        }    }

Every new story starts as a draft. It moves to review only when Story.submit runs its submit transition.

Markdown for agents: /docs/errors/data.lifecycle_owned_field.md.Built from Jadpo main at aee2e8f.