Identity · rule
route.confirm_invalid
A route's confirm: holds something other than Confirmation.passkey, or no signed-in person could confirm the route.
Area 8, Identity; not declinable; the next step is usually the agent's.
Why Jadpo refuses it
confirm: makes a route run only once the signed-in person presents one
of their own passkeys for that one request, so a stolen session or token
isn't enough. Confirmation.passkey is the only way a route asks for that,
and any other value is refused rather than read as no confirmation, since
the route you meant to protect would then run without one.
It also needs a person to confirm. A route open to anyone reads no
credential, so nobody is signed in whose passkey it could be, and a route
that passes on current_principal.service runs for a service, which signs
in with its key and holds no passkey.
What it looks like
main.jadpo:
type Memo = Text { max_length: 200}type AddMemo = Input { text: Memo}action add_memo(input: AddMemo) -> Unit { var memo: Memo = input.text assert memo != ""}routes Memos { prefix: /memos POST / { confirm: passkey input: AddMemo status: SuccessStatus.no_content run: add_memo(input) }}
error passkey isn't a Confirmation
--> main.jadpo:18:18
|18 | confirm: passkey | ^^^^^^^ not `Confirmation.passkey`
- reason
confirm:says what the signed-in person presents before the route runs, andConfirmation.passkey, one of their own passkeys for this one request, is the only way there is.- next
- Write
confirm: Confirmation.passkey(agent) - rule
- route.
confirm_ invalid - help
- https://jadpo.
dev/docs/errors/route. confirm_ invalid
(agent) at the end of the next: line means your coding agent can make the fix itself: the value has only one spelling.
A route anyone may call has nobody signed in to confirm it:
type Memo = Text { max_length: 200}type AddMemo = Input { text: Memo}action add_memo(input: AddMemo) -> Unit { var memo: Memo = input.text assert memo != ""}routes Memos { prefix: /memos POST / { authentication: RouteAuthentication.none confirm: Confirmation.passkey input: AddMemo status: SuccessStatus.no_content run: add_memo(input) }}
error POST /memos is open to anyone, so no one signed in can confirm it
--> main.jadpo:19:9
|19 | confirm: Confirmation.passkey | ^^^^^^^ needs a signed-in person
- reason
confirm: Confirmation.passkeyasks the signed-in person for one of their own passkeys, andauthentication: RouteAuthentication.nonereads no credential, so there is no person whose passkey it could be.- next
- Remove
authentication: RouteAuthentication.noneso callers sign in (agent) - rule
- route.
confirm_ invalid - help
- https://jadpo.
dev/docs/errors/route. confirm_ invalid
And a route that runs for a service has no passkey to ask for:
entity Robot { id: Uuid name: Text { max_length: 40 unique: true }}principal { service: { subject: Robot.name }}authentication { service_key: {}}action run_robot(robot: Principal.service) -> Unit { assert robot.subject != ""}routes Robots { prefix: /robots POST / { confirm: Confirmation.passkey status: SuccessStatus.no_content run: run_robot(current_principal.service) }}
error POST /robots runs for a service, which has no passkey
--> main.jadpo:27:9
|27 | confirm: Confirmation.passkey | ^^^^^^^ asks for a passkey29 | run: run_robot(current_principal.service) | ----------------- a service's call
- reason
confirm: Confirmation.passkeyasks the signed-in person for one of their own passkeys; a service signs in with its key and holds none.- next
- Pass
current_principal.user, or removeconfirm:from a route only services call (agent) - rule
- route.
confirm_ invalid - help
- https://jadpo.
dev/docs/errors/route. confirm_ invalid
How to fix it
If the value is wrong, write Confirmation.passkey:
confirm: Confirmation.passkeyThe app must have passkey: in sign_in:, which brings magic links and an
email connection beside it. POST /memos now runs only once the signed-in
person presents one of their own passkeys.
If the route is open to anyone, remove authentication: RouteAuthentication.none, so callers sign in:
POST / { confirm: Confirmation.passkey ... }
Callers who aren't signed in now get a 401, and the signed-in person confirms each request.
If a person should call the route, pass current_principal.user, with
the action taking a Principal.user:
run: add_memo(input, current_principal.user)A service's key no longer reaches the route, and the person who calls it
presents their passkey. If only services call it, remove confirm:.
Related
Markdown for agents: /docs/errors/route.confirm_invalid.md.Built from Jadpo main at e00e61f.