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

ErrorsPolicy · rule

policy.scope_missing

On this page

An entity names a role held in another record, or belongs to the app's tenant, but has no reference to that record.

Area 9, Policy; not declinable; the next step is usually the agent's.

Why Jadpo refuses it

A membership role is held in a record, its scope, such as an editor of a company. A role applies to another entity's record through that record's reference to the scope: an editor of a company may read the ledgers whose company_id names that company. A Ledger with no company_id has no company, so CompanyRole.editor could never let anyone in.

Naming a tenant in root policy { } works the same way. Every grant on a tenant's records applies only within the tenants where the caller has a membership, so each entity needs its own reference to the tenant, or says that every tenant shares it.

What it looks like

main.jadpo:

example
type Handle = Text {    max_length: 40}entity User {    id: Uuid    handle: Handle {        unique: true    }}principal {    user: {        subject: User.handle    }}type CompanyRole = Enum {    owner    editor}entity Company {    id: Uuid}entity CompanyMembership {    id: Uuid    company_id: Company.id {        on_delete: OnDelete.cascade    }    user_id: User.id {        on_delete: OnDelete.cascade    }    role: CompanyRole    membership: {        scope: company_id        member: user_id        role: role    }}entity Ledger {    id: Uuid    policy: {        read: [CompanyRole.editor]    }}
jadpo checkcheck failed: 1 error, 1 file

error Ledger has no reference to Company

--> main.jadpo:48:16

   |48 |         read: [CompanyRole.editor]   |                ^^^^^^^^^^^^^^^^^^ a role held in a `Company`
reason
CompanyRole is held in a Company (CompanyMembership's scope:), and a role applies to a record through the record's reference to its scope, so Ledger needs a field typed Company.id.
next
Add a reference to Company to Ledger, or name someone else (agent)
rule
policy.scope_missing
help
https://jadpo.dev/docs/errors/policy.scope_missing

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

When root policy { } names Company as the tenant, an entity with no reference to Company is refused the same way, whatever its grants name:

example
type Handle = Text {    max_length: 40}entity User {    id: Uuid    handle: Handle {        unique: true    }    policy: {        tenant: Tenancy.shared    }}principal {    user: {        subject: User.handle    }}type CompanyRole = Enum {    owner    editor}entity Company {    id: Uuid}entity CompanyMembership {    id: Uuid    company_id: Company.id {        on_delete: OnDelete.cascade    }    user_id: User.id {        on_delete: OnDelete.cascade    }    role: CompanyRole    membership: {        scope: company_id        member: user_id        role: role    }}entity Ledger {    id: Uuid    policy: {        read: [Access.authenticated]    }}policy {    tenant: Company}
jadpo checkcheck failed: 1 error, 1 file

error Ledger doesn't belong to a Company

--> main.jadpo:48:8

   |48 | entity Ledger {   |        ^^^^^^ no reference to `Company`
reason
Root policy { } names Company as the tenant, so every entity carries its own reference to it and its grants apply only within the Companys where the caller has a membership; an entity every tenant shares says tenant: Tenancy.shared.
next
Add a field typed Company.id to Ledger, or tenant: Tenancy.shared to its policy: (agent)
rule
policy.scope_missing
help
https://jadpo.dev/docs/errors/policy.scope_missing

How to fix it

The question is whether a ledger belongs to a company.

If each ledger belongs to a company, add a reference to Company. The same field is the ledger's tenancy reference when Company is the tenant:

example
entity Ledger {    id: Uuid    company_id: Company.id {        on_delete: OnDelete.cascade    }    ...}

A company's editors may now read the ledgers whose company_id names that company, and no one else may. Deleting a company deletes its ledgers.

If ledgers belong to no company, in an app with no tenant, name someone the grant can check without one, such as anyone signed in:

example
        read: [Access.authenticated]

Anyone signed in may read every ledger.

If every tenant shares the ledgers, say so with tenant: Tenancy.shared in Ledger's policy::

example
    policy: {        tenant: Tenancy.shared        read: [Access.authenticated]    }

A ledger belongs to no company, and its grants apply as they would without tenancy, so anyone signed in may read every ledger. A role held in a company still can't be named in its grants, since a ledger has no company.

Markdown for agents: /docs/errors/policy.scope_missing.md.Built from Jadpo main at aee2e8f.