Skip to content

Diagnostic codes

Every type-checker error and warning carries a stable AG#### code, and every agency lint finding carries a stable AL#### code. Look one up with agency explain <code> (e.g. agency explain AG2005), or suppress a type-checker one on the next line with // @tc-ignore AG####.

Types and aliases

CodeMessage
AG1001Type parameter '{param}' (no default) must come before parameters that have defaults in '{alias}'.
AG1002Type '{alias}' is not a value-parameterized type but was given {count} value {argumentWord} (referenced in '{context}').
AG1003{alias} expects at most {max} value {argumentWord}, got {count} (referenced in '{context}').
AG1004'{alias}' is a value-parameterized type and requires value arguments — write '{alias}({formals})' (referenced in '{context}').
AG1005{alias} requires at least {min} value {argumentWord} (referenced in '{context}').
AG1006Type alias '{alias}' is not defined (referenced in '{context}').
AG1007Generic type '{alias}' requires type arguments (referenced in '{context}').
AG1008{alias} expects {expected} type {argumentWord}, got {count} (referenced in '{context}').
AG1009Unknown generic type '{alias}' (referenced in '{context}').
AG1010Type '{alias}' is not a generic type (referenced in '{context}').
AG1011{alias} expects at most {max} type {argumentWord}, got {count} (referenced in '{context}').
AG1012{alias} requires at least {min} type {argumentWord} (referenced in '{context}').
AG1013&#123;name&#125; is not a type; {hint}

Assignability and checking

CodeMessage
AG2001Type '{actual}' is not assignable to type '{expected}' ({context}).
AG2002Type '{actual}' is not assignable to type 'boolean' (condition).
AG2003Unknown property '{key}' on type '{expected}' ({context}).
AG2004Variable '{name}' has no type annotation (strict mode).
AG2005Type '{actual}' is not assignable to type '{expected}'.
AG2006For-loop iterable must be an array or Record, got '{actual}'.
AG2007{kind} '{name}' has validated parameters but its return type is not a Result type. Validated parameters can short-circuit with a failure, so the return type must be 'Result<...>'.
AG2008Property '{field}' is not available on every member of '{union}'; narrow the value (e.g. with a guard) before accessing it.
AG2009'.{field}' is only available on a {branch} Result; guard with 'if (isSuccess(r))' / 'if (isFailure(r))', use 'r catch …', or 'match (r) { … }'.
AG2010Cannot {op} values of different dimensions ({leftDim} and {rightDim}): '{left}' and '{right}'.
AG2011Property '{property}' does not exist on type '{type}'.
AG2012Not all code paths return a value in '{fn}'.

Interrupts, effects, and handlers

CodeMessage
AG3001The '!' validation syntax is not allowed on handler parameters. Validate the data inside the handler body if needed.
AG3002Effect '{effect}' is declared more than once in the same file.
AG3003Conflicting payload types for effect '{effect}'. All declarations of an effect must agree on its payload.
AG3004Named arguments are not allowed on 'raise'/'interrupt'. Pass the data positionally.
AG3005Effect '{effect}' expects data {payload}, but none was supplied.
AG3006Effect '{effect}' data field '{field}' is missing.
AG3007Effect '{effect}' data field '{field}' has the wrong type.
AG3008Effect '{effect}' data does not match the declared {payload}.
AG3009Function '{fn}' may throw interrupts [{effects}] but is not inside a handler.
AG3011interrupt is not allowed inside a callback body (callback registered on '{hook}' may raise [{effects}]). 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.
AG3012'raises {ref}' is not an effect set. Declare '{ref}' with 'effectSet' (not 'type'), or use an inline set like '<...>'.
AG3013{kind} '{name}' raises effect '{effect}', which exceeds its declared 'raises {declared}'. Add '{effect}' to the clause.
AG3014{who} may raise any effect (its type has no 'raises' clause), which exceeds the 'raises <{allowed}>' allowed by type '{type}'. Add a 'raises' clause to the value's type.
AG3015{who} raises effect '{effect}', which exceeds the 'raises <{allowed}>' allowed by type '{type}'. Add '{effect}' to the clause, or use a target type that allows it.
AG3016'{callee}' can interrupt, and a finalize block cannot contain interrupts. A finalize runs while its scope shuts down, so there is nothing to resume.
AG3017Cannot use {kind} at the top level of a file. Top-level code runs at initialization, which cannot branch, loop, or wait — move it inside a node or a function.
AG3018A handler cannot be registered at the top level of a file. Handlers must be inside a node or a function, where there is execution for them to guard.

Names, scope, and reserved words

CodeMessage
AG4001'{name}' shadows an imported function.
AG4002'{name}' is a reserved built-in; cannot be redefined.
AG4003'{name}' is a reserved built-in type; cannot be redefined.
AG4004Function '{name}' is not defined.
AG4005Cannot reassign to constant '{name}'.
AG4006&#123;keyword&#125; is a reserved block keyword. Write &#123;keyword&#125; &#123; ... &#125; or &#123;keyword&#125;(args) &#123; ... &#125; directly — the as keyword is not supported on {keyword} blocks (there's nothing to bind).
AG4007Variable '{name}' is not defined.
AG4008'{name}' is not defined in '{module}'.
AG4009Cannot find module '{module}'.
AG4010'{name}' is defined in '{module}' but is not exported. Add the 'export' keyword to its definition.

Match and narrowing

CodeMessage
AG5002match is not exhaustive: missing {missing}.
AG5003&#123;name&#125; here binds the value; it does not test the type. Did you mean p: &#123;name&#125; or is &#123;name&#125;?

Calls, tools, and LLM usage

CodeMessage
AG6001'regex' cannot appear in an llm() structured-output type ({context}); LLMs can't return regex values through JSON.
AG6002Cannot interpolate parameter '{param}' in doc string — parameter values are not known when the tool description is sent to the LLM. Use a global variable instead.
AG6003.partial() requires named arguments, e.g. fn.partial(a: 5).
AG6004Unknown parameter '{name}' in .partial() call. '{fn}' has parameters: {params}.
AG6005Argument type '{actual}' is not assignable to parameter type '{expected}' in .partial() call to '{fn}'.
AG6006Named arguments are not supported on built-in method '.{method}()'.
AG6007Method '.{method}()' expects {expected} argument(s), got {count}.
AG6008Method '.{method}()' expects at least {min} argument(s), got {count}.
AG6009Method '.{method}()' expects {min}–{max} argument(s), got {count}.
AG6010Argument type '{actual}' is not assignable to parameter type '{expected}' in call to '.{method}()'.
AG6011Named arguments can only be used with Agency-defined functions, not '{fn}'.
AG6012'{fn}' does not accept the named argument '{name}'. Allowed: {allowed}.
AG6013Duplicate named argument '{name}' in call to '{fn}'.
AG6014Named argument '{name}' on '{fn}' expects type '{expected}', got '{actual}'.
AG6015'{fn}' does not accept a block argument.
AG6016Expected {expected} argument(s) for '{fn}', but got {count}.
AG6017Expected at least {min} argument(s) for '{fn}', but got {count}.
AG6018Expected {min}-{max} argument(s) for '{fn}', but got {count}.
AG6019Argument type '{actual}' is not assignable to parameter type '{expected}' in call to '{fn}'.
AG6020Splat argument must be an array, got '{actual}' in call to '{fn}'.
AG6021Splat element type '{actual}' is not assignable to parameter type '{expected}' in call to '{fn}'.
AG6022Type '{actual}' is not assignable to pipe slot of type '{expected}'.
AG6023Splat argument cannot follow a named argument in call to '{fn}'.
AG6024Positional argument cannot follow a named argument in call to '{fn}'.
AG6025Unknown named argument '{name}' in call to '{fn}'.
AG6026Named argument '{name}' conflicts with positional argument at position {position} in call to '{fn}'.
AG6027Positional argument cannot feed variadic parameter '{param}' when it is also bound by name in call to '{fn}'.
AG6028Tool '{tool}' has required function-typed parameter '{param}' is unbound. Bind it with .partial({param}: <value>) before passing as a tool.
AG6029Tool '{tool}' has required function-typed parameter '{param}' is unbound ({type}). Bind it with .partial({param}: <value>) before passing as a tool.
AG6030Tool '{tool}' will be exposed to the LLM without optional function-typed parameter(s): {params}. The function body must be prepared to run with the declared default for each.
AG6031saveDraft() cannot be called at module top level — there is no enclosing function, node, or block scope to save a draft for.
AG6032A scope can declare at most one finalize block. Combine the logic into one block.
AG6033A finalize block cannot go inside {construct}. Declare it at the top level of the function or block body. A finalize is always active, so nesting it in control flow has no meaning.
AG6034saveDraft() has no effect inside a finalize block. The value the finalize returns is already the partial result. Return the value instead.
AG6035A finalize block cannot go in a node body. Nothing above a node consumes a partial result yet. Put the finalize in a function or a guard block instead.
AG6036This scope has a finalize block, so a return expression cannot bury a call inside a bigger expression. If the call were stopped, the expression would consume its partial result before the finalize could run. Assign the call to a local first, then return the local.
AG6037finalize binder '{name}' collides with a variable that already exists in this scope. Pick a fresh name. The finalize body reads the scope's locals directly, so a colliding binder would silently shadow the local.
AG6038finalize yields a single value — the scope's saved draft. Use one binder: finalize as {name} { ... }.
AG6039Parameter '{name}' on '{fn}' has no default but comes after a defaulted parameter. Put defaulted parameters last, so an omitted argument is always a trailing one.

Static init, config, and imports

CodeMessage
AG7001Only 'static const' declarations can be exported. Use 'export static const {name} = ...' instead.
AG7002{contextLabel} cannot call &#123;builtin&#125;(...) — {reason}, but static initializers run once at process startup before any per-run state exists. Move this call into a node or a function called from a node.
AG7003{contextLabel} cannot interrupt(...) — interrupts pause the per-run execution stack, but static initializers run once at process startup before any agent run has begun. Move this into a node body.
AG7004Cannot reassign static &#123;name&#125; at module top level — statics are immutable after initialization. Use a global (const/let without static) if you need a mutable value.
AG7005Cannot mutate static &#123;name&#125; via .&#123;method&#125;(...) at module top level — statics are deep-frozen after initialization. Use a global (const/let without static) if you need a mutable value.
AG7006Function '{name}' cannot be both destructive and idempotent — those markers are contradictory. Pick one.

Code templates and holes

CodeMessage
AG8001This file is a template with unfilled holes ({names}) and cannot be run directly. Load it with loadTemplate and fill it first.
AG8002The hole #&#123;name&#125; is in a position that gives it no expected type. Annotate it, for example #&#123;name&#125;: string.
AG8003Generator '{name}' may raise {effects}, so it cannot run at compile time. Compilation installs no interrupt handlers, so those operations could not complete anyway. Move the effectful work out of the generator.
AG8004Generator '{name}' cannot be checked for effects: {reason}. An empty effect list from an incomplete reading means nothing, so it is refused rather than run.
AG8005&#123;name&#125; must be imported from another file to be used in a splice. A generator cannot be defined in the file that splices it, because it has to be compiled first.
AG8006The generator &#123;name&#125; reaches non-Agency code through &#123;importPath&#125;. Compile-time generators may import only std:: modules and relative .agency files, because JavaScript raises no interrupts and cannot be checked. Set allowNonAgencyGenerators in your config to permit it.
AG8007The generator &#123;name&#125; returned a &#123;actual&#125; fragment, but this splice is in {position} position and needs a &#123;expected&#125; fragment.
AG8008The generator &#123;name&#125; failed while running: {reason}
AG8009A generator module cannot itself contain a splice. Move the inner generation into a separate module.
AG8010Generated code refers to &#123;name&#125;, which it neither declares nor imports. Generated code may use only names it declares itself and names it imports.
AG8011The splice argument &#123;name&#125; is declared in this file, so it does not exist yet when the generator runs. Splice arguments may be literals, code literals, or imported names.
AG8012The generator &#123;name&#125; declares &#123;declared&#125;, which this file already declares. Generated declarations may not replace existing ones.
AG8013The generator &#123;name&#125; produced an exported declaration (&#123;declared&#125;). Generated declarations cannot be exported yet, because other files resolve imports without running generators. Remove the export.
AG8014The generator &#123;name&#125; returned {kind}, which cannot sit at the top level of a file. Top-level code runs at initialization, which cannot branch, loop, or wait.
AG8015&#123;name&#125; is not defined in this template. A template can only use names it declares or imports itself, because a hole hides whatever fills it. Move the code that defines &#123;name&#125; into this template, or move the code that uses it into the fragment that defines it.

Lint

CodeMessage
AL0001'{name}' is imported but never used.
AL0002'{name}' is exported but has no docstring.
AL0003'{name}' is already available without an import.