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

query.include_depth

On this page

A query's includes nest more than two levels deep: records inside records inside records.

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

Why Jadpo refuses it

Each include is one more database query, however many records the result holds. Keeping includes to two levels keeps a query's cost easy to see from its shape. A deeper shape is read by a second query instead.

Jadpo won't split the query for you, because the split decides what the result holds and how its readers get the rest.

What it looks like

main.jadpo:

example
type Name = Text {    max_length: 80}entity Territory {    id: Uuid    name: Name}entity Publisher {    id: Uuid    territory_id: Territory.id {        on_delete: OnDelete.restricted    }}entity Author {    id: Uuid    publisher_id: Publisher.id {        on_delete: OnDelete.restricted    }}entity Book {    id: Uuid    author_id: Author.id {        on_delete: OnDelete.cascade    }}type TerritoryView = Output {    pick: [Territory.name]}type PublisherView = Output {    territory: TerritoryView}type AuthorView = Output {    publisher: PublisherView}type BookView = Output {    pick: [Book.id]    author: AuthorView}query books() -> List<BookView> {    from: Book    order: [Book.id asc]    limit: 20    include: {        author: {            via: Book.author_id            include: {                publisher: {                    via: Author.publisher_id                    include: {                        territory: Publisher.territory_id                    }                }            }        }    }}
jadpo checkcheck failed: 1 error, 1 file

error Includes nest at most two levels

--> main.jadpo:58:21

   |58 |                     include: {   |                     ^^^^^^^ a third level
reason
Each include is one more database query, and a query's includes nest up to two levels so its cost stays easy to see; a deeper shape is a second query called from the action.
next
Read the deeper records with a query of their own (human)
rule
query.include_depth
help
https://jadpo.dev/docs/errors/query.include_depth

(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 what each book in the list carries, and how a reader finds its publisher's territory.

How to fix it

The question is whether whoever reads the list needs each publisher's territory.

If they do, stop the includes at the publisher, give its territory_id, and read the territory with a query of its own:

example
type PublisherView = Output {    pick: [Publisher.territory_id]}
example
    include: {        author: {            via: Book.author_id            include: {                publisher: Author.publisher_id            }        }    }
example
query territory_by_id(territory_id: Territory.id) fails TerritoryNotFound -> TerritoryView {    from: Territory    where: Territory.id == territory_id    missing: TerritoryNotFound}

books now costs three database queries: the books, their authors and their publishers. Each publisher carries its territory_id, and territory_by_id reads that territory when it is needed, as one more query.

If they don't, stop the includes at the publisher and leave the territory out:

example
type PublisherView = Output {    pick: [Publisher.id]}

books costs three database queries, and its results no longer say anything about territories.

Markdown for agents: /docs/errors/query.include_depth.md.Built from Jadpo main at aee2e8f.