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}
AG1014Cannot cast &#123;from&#125; to &#123;to&#125; because neither type fits the other. If this is intentional, write &#123;expr&#125; as unknown as &#123;to&#125;.
AG1015A checked cast validates the value at runtime, and &#123;type&#125; has no schema to validate against. Remove the ! to cast without checking.
AG1016A cast is not allowed in this position. Add parentheses: (&#123;left&#125; &#123;op&#125; &#123;right&#125;) as &#123;type&#125; or &#123;left&#125; &#123;op&#125; (&#123;right&#125; as &#123;type&#125;).
AG1017This checked cast runs validators that can pause the program, and it cannot be resumed safely in this position. Move it to its own line: const value = &#123;cast&#125;.
AG1018&#123;expr&#125; is a &#123;from&#125;. A cast does not unwrap it. Unwrap the Result first, with match or catch, then cast the value if you still need to.
AG1019&#123;cast&#125; runs validators that can pause the program, and a module-level initializer or a parameter default cannot pause. Do the cast inside a node or a def.
AG1020&#123;cast&#125; runs validators that can pause the program, and a handler body cannot pause. Do the cast before the handle block and use the value here.

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}'.
AG2013The first argument to failure() is the message shown to a person or a model, so it must be a string. Got '{actual}'.
AG2014The second argument to failure() is its structured data, so it must be an object. Got '{actual}'.
AG2015This function declares '{expected}' as its failure data, so failure() needs a second argument. To allow a failure with no data, declare the return type as 'Result<{success}, {expected} | null>'.
AG2016A Result's second type parameter is its failure data, and failure data must be an object. Got '{actual}' ({context}). A failure's message is always a string and is not named in the type.
AG2017failure() cannot take a splat. Codegen appends the checkpoint and function name to every failure() call by position, and a splat of unknown width would displace them. Pass the message and data directly.

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.
AG3019@{tag} names '{field}', which effect '{effect}' does not carry.
AG3020@{tag} arguments must be bare field names, each named once (effect '{effect}').
AG3021@{tag} appears more than once on effect '{effect}'.
AG3022Conflicting @always scopes for effect '{effect}'. All tagged declarations of an effect must agree.
AG3023@{tag} is only valid on an effect declaration.

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.
AG4011'{name}' is not accessible under --agency-only. It reaches JavaScript's Function or prototype chain, which pure Agency code may not use.
AG4012Cannot redeclare parameter '{name}' with '{declKind}'. Reads after the redeclare would still see the parameter. Assign to it instead, or pick a different name.
AG4013{violation}

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 a required function-typed parameter '{param}' that is unbound. Bind it with .partial({param}: <value>) before passing it as a tool.
AG6029Tool '{tool}' has a required function-typed parameter '{param}' that is unbound (its type is {type}). Bind it with .partial({param}: <value>) before passing it 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.
AG6040'{expr}' is passed as a tool, but it is a value of type '{actual}', not a function.{shadowHint}

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.
AG7007Type '{alias}' takes value argument '{name}', which is {what}. A value argument must be a literal, a 'static const', an imported name, or a value parameter of the enclosing type alias.
AG7008{contextLabel} calls &#123;fn&#125;, which may interrupt [{effects}]. 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, or answer it at the site by ending the statement with with approve.

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;. Running a generator loads its file and every file that one imports, and loading a JavaScript module runs it, even when the generator calls nothing from it. JavaScript raises no interrupts and cannot be checked. Move &#123;name&#125; into a file that imports only std:: modules and relative .agency files, and check what those files import in turn: one of them importing a JavaScript package is the same problem one step down. If the generator itself needs the JavaScript, set allowNonAgencyGenerators in your config, which switches this check off for every generator.
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.
AG8016&#123;file&#125; contains a splice, and generator execution was declined for this check, so &#123;name&#125; was not run.
AG8017Generated code from &#123;generator&#125; uses the name &#123;name&#125;. Names starting with two underscores are reserved for the compiler.

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.