Diagnostic Reference
Diagnostics include codes so docs, CI, and editors can link to explanations. During the alpha cycle, read the code together with the diagnostic area and message. Some parser and compiler areas reuse the same numeric code.
Format
Section titled “Format”anvil: scan produced 1 diagnostic(s) (1 error(s), 0 warning(s))
path/to/file.go:12:4: ERROR ANVIL###: message hint: actionable fix related: other/file.go:7:1: supporting context 12 | source line | ^Common Categories
Section titled “Common Categories”- Marker errors
- Route path errors
- Handler signature errors
- Request binding errors
- Validation errors
- Middleware errors
- Dependency graph errors
- Manifest rule errors
- Starlark rule errors
Parser Codes
Section titled “Parser Codes”These codes come from the first compiler stage, before route plans and generated files are written.
| Code | Meaning |
|---|---|
ANVIL001 | Go package loading failed. The hint contains the underlying package loader error. |
ANVIL101 | A marked endpoint is missing its required handler method. |
ANVIL201 | A controller embeds sdk.Controller but has no route table. |
ANVIL202 | A controller has Routes, but it is not a struct route table. |
ANVIL203 | A route marker is missing a path tag. |
ANVIL204 | A route marker has no matching handler method. |
ANVIL205 | An HTTP handler has an invalid signature. |
ANVIL206 | A route-table field is ignored because it is not an Anvil marker. |
ANVIL207 | A route-table field is unexported. Route field names become handler method names. |
ANVIL208 | A request field declares more than one binding source. |
ANVIL209 | A request source/key binding is declared more than once. |
ANVIL210 | A validation tag contains an unknown or malformed validation rule. |
ANVIL211 | A middleware type does not implement the protocol middleware contract where it is used. |
ANVIL212 | A group field is ignored because it is not a named component type. |
ANVIL213 | A WebSocket handler has an invalid signature. |
ANVIL214 | A type has a handler-looking method but no Anvil endpoint marker. |
ANVIL215 | A binding tag has an invalid or empty key. |
ANVIL216 | A validation rule is not valid for the field type. |
ANVIL217 | A request type has a Validate method with the wrong signature. |
ANVIL218 | A cross-field validation target is invalid. |
ANVIL219 | A bound request field cannot be decoded from text. |
ANVIL220 | sdk.Use[...] was placed directly on an endpoint type where a group or policy boundary is required. |
ANVIL301 | A gRPC service has no exported RPC methods. |
ANVIL302 | A gRPC method has an invalid unary or stream signature. |
ANVIL401 | A GraphQL endpoint is missing Execute. |
ANVIL402 | A GraphQL Execute or Subscribe method has an invalid signature. |
ANVIL501 | A queue job is missing Handle. |
ANVIL502 | A queue job Handle method has an invalid signature. |
ANVIL900 | A scanner was misconfigured by Anvil or embedded tooling. |
Compiler Codes
Section titled “Compiler Codes”These codes come from the compiler stage after parser output has been turned into route, group, and dependency plans.
| Code | Meaning |
|---|---|
ANVIL301 | An HTTP route path is invalid. Paths must start with /, use :param syntax, and avoid empty segments. |
ANVIL302 | Two HTTP routes collide after method and path normalization. |
ANVIL303 | A controller or group is mounted under more than one parent group. |
ANVIL304 | The HTTP group tree contains a cycle. |
ANVIL305 | A generated component dependency graph contains a cycle. |
Built-In Manifest Rules
Section titled “Built-In Manifest Rules”| Rule | Level | Meaning |
|---|---|---|
http.operation_id.unique | Error | Two HTTP routes produced the same operation ID. |
http.request.validator | Warning | An unsafe method has a request type but no Validate(ctx sdk.Ctx) error. |
http.middleware.named | Error | HTTP middleware uses an unnamed type. |
http.route.root | Warning | A route is mounted at /. |
http.group.empty | Warning | A group has no routes in its hierarchy. |
http.middleware.duplicate | Warning | A middleware type appears more than once in one HTTP chain. |
http.route.shadowing | Warning | A route path shadows a child group path. |
Middleware Diagnostics
Section titled “Middleware Diagnostics”ANVIL211 means a middleware marker was found, but the type does not implement
the middleware shape required by that protocol.
Examples:
- A GraphQL policy uses a type with
HandleHTTPbut noHandleGraphQL. - A gRPC group uses a type with
HandleGRPC(ctx context.Context)instead ofHandleGRPC(ctx sdk.GRPCCtx) (any, error). - A queue group uses a type whose
HandleQueuemethod returns the wrong type.
The fix is to move the middleware to the protocol it supports or change the method signature to the SDK contract.
ANVIL220 means sdk.Use[...] was placed directly inside a GraphQL endpoint,
gRPC service, or queue job. Move the marker to a parent sdk.Group. For
GraphQL endpoint-specific middleware, use sdk.GraphQLEndpointWith[Policy] and
put sdk.Use[...] inside the policy type.
Warning Behavior
Section titled “Warning Behavior”Parser diagnostics include both ERROR and WARN levels. anvil scan prints
warnings and exits successfully when there are no errors. anvil generate,
anvil manifest, anvil openapi, and anvil testbed stop when the scan stage
returns any diagnostic, including warnings, because those commands need a clean
source graph before they write generated artifacts or derived manifests.
Manifest rule diagnostics use ERROR and WARNING internally. When they are
rendered by the CLI, warnings appear as WARN. Rule errors stop generate and
lint; rule warnings are printed by lint while generate continues.
Good Diagnostics
Section titled “Good Diagnostics”A useful diagnostic includes:
- The exact source location
- The rejected symbol
- The rule Anvil enforced
- An example of the accepted shape
Write diagnostics for the developer fixing the code, not for the compiler author.