---
name: "Interrupts, effects, and handlers"
---

# Interrupts, effects, and handlers

<a id="ag3001"></a>

## AG3001 — The '!' validation syntax is not allowed on handler parameters. Validate the data inside the handler body if needed.

*Default severity: error.*

Handler parameters carry the payload of an interrupt, and the `!` validation syntax is not allowed on them. Validation there would run at a point in the flow where a failure has nowhere safe to go.

**How to fix:** drop the `!` from the handler parameter and validate the data inside the handler body if you need to.

<a id="ag3002"></a>

## AG3002 — Effect '&#123;effect&#125;' is declared more than once in the same file.

*Default severity: error.*

An effect was declared more than once in the same file. Each effect name should be introduced by a single declaration so its payload shape has one definition.

**How to fix:** remove the duplicate declaration.

<a id="ag3003"></a>

## AG3003 — Conflicting payload types for effect '&#123;effect&#125;'. All declarations of an effect must agree on its payload.

*Default severity: error.*

Two declarations of the same effect disagree about its payload type. Every declaration of an effect must agree on the data it carries.

**How to fix:** make the declarations match, or consolidate them into one.

<a id="ag3004"></a>

## AG3004 — Named arguments are not allowed on 'raise'/'interrupt'. Pass the data positionally.

*Default severity: error.*

`raise` and `interrupt` take their payload positionally, not as named arguments. Their data is a single positional value.

**How to fix:** pass the data positionally, e.g. `raise MyEffect(payload)`.

<a id="ag3005"></a>

## AG3005 — Effect '&#123;effect&#125;' expects data &#123;payload&#125;, but none was supplied.

*Default severity: error.*

The effect declares a payload, but this `raise`/`interrupt` supplied none. A declared payload is required at the raise site.

**How to fix:** pass the data the effect expects.

<a id="ag3006"></a>

## AG3006 — Effect '&#123;effect&#125;' data field '&#123;field&#125;' is missing.

*Default severity: error.*

The effect's payload is a structured type, and a required field of it was not supplied at the raise site.

**How to fix:** add the missing field to the payload you pass.

<a id="ag3007"></a>

## AG3007 — Effect '&#123;effect&#125;' data field '&#123;field&#125;' has the wrong type.

*Default severity: error.*

A field of the effect's payload was supplied with a value whose type does not match what the effect declares for that field.

**How to fix:** pass a value of the declared type for that field.

<a id="ag3008"></a>

## AG3008 — Effect '&#123;effect&#125;' data does not match the declared &#123;payload&#125;.

*Default severity: error.*

The payload supplied at the raise site does not match the shape the effect declares. The whole value, not just one field, is off.

**How to fix:** construct the payload to match the effect's declared type.

<a id="ag3009"></a>

## AG3009 — Function '&#123;fn&#125;' may throw interrupts [&#123;effects&#125;] but is not inside a handler.

*Default severity: warning.*

This function may raise interrupts, but it is called from a place that is not inside a matching handler. An unhandled interrupt at runtime has no `handle` block to receive it. This is a warning because the handler may be installed dynamically at a point the checker cannot see.

**How to fix:** wrap the call in a `handle` block for the effects it may raise, or confirm a handler is installed higher up.

<a id="ag3011"></a>

## AG3011 — `interrupt` is not allowed inside a callback body (callback registered on '&#123;hook&#125;' may raise [&#123;effects&#125;]). Callbacks fire as side effects; their body cannot pause execution to ask the user a question. Move the `interrupt` into the calling node/function instead, or use a runtime guard if you wanted budget enforcement.

*Default severity: error.*

Callbacks fire as side effects at points where execution cannot pause, so their body may not `interrupt` — an interrupt would need to stop the run to ask the user something, which a callback has no way to do.

**How to fix:** move the `interrupt` into the calling node or function. If you only wanted a runtime budget check, use a runtime guard instead.

<a id="ag3012"></a>

## AG3012 — 'raises &#123;ref&#125;' is not an effect set. Declare '&#123;ref&#125;' with 'effectSet' (not 'type'), or use an inline set like '&lt;...&gt;'.

*Default severity: error.*

A `raises` clause must name an effect set, but the reference given is declared as a plain `type`, not an `effectSet`. The two are different: only an effect set enumerates raisable effects.

**How to fix:** declare the reference with `effectSet` instead of `type`, or use an inline effect set in angle brackets.

<a id="ag3013"></a>

## AG3013 — &#123;kind&#125; '&#123;name&#125;' raises effect '&#123;effect&#125;', which exceeds its declared 'raises &#123;declared&#125;'. Add '&#123;effect&#125;' to the clause.

*Default severity: error.*

The function or node raises an effect that its own `raises` clause does not list. The clause is a contract: it must cover every effect the body can raise.

**How to fix:** add the effect to the `raises` clause, or stop raising it.

<a id="ag3014"></a>

## AG3014 — &#123;who&#125; may raise any effect (its type has no 'raises' clause), which exceeds the 'raises &lt;&#123;allowed&#125;&gt;' allowed by type '&#123;type&#125;'. Add a 'raises' clause to the value's type.

*Default severity: error.*

A value is being used where the target type limits which effects may be raised, but the value's own type has no `raises` clause — so it could raise anything, which exceeds that limit.

**How to fix:** add a `raises` clause to the value's type so the checker can see it stays within bounds.

<a id="ag3015"></a>

## AG3015 — &#123;who&#125; raises effect '&#123;effect&#125;', which exceeds the 'raises &lt;&#123;allowed&#125;&gt;' allowed by type '&#123;type&#125;'. Add '&#123;effect&#125;' to the clause, or use a target type that allows it.

*Default severity: error.*

A value raises an effect that the target type's `raises` clause does not allow. The target restricts the effect set, and this value steps outside it.

**How to fix:** add the effect to the target type's clause, or use a target type that permits it.

<a id="ag3016"></a>

## AG3016 — '&#123;callee&#125;' can interrupt, and a finalize block cannot contain interrupts. A finalize runs while its scope shuts down, so there is nothing to resume.

*Default severity: error.*

An interrupt pauses the program and waits for an answer. When the answer arrives, the program resumes from the paused step. A finalize block runs while an abort shuts its scope down, so there is no step to resume from. That is why a finalize cannot interrupt, and cannot call a function that interrupts.

The check follows calls into functions defined in your own files. It cannot see into imported functions. If an imported function interrupts inside a finalize at runtime, the finalize counts as failed and the scope falls back to its saved draft.

**How to fix:** only compute values inside the finalize, using the variables you already have. If you need to ask the user something, ask in the normal body, before the work that can trip.
