When each code can fire
slurp validate parses and runs the compile-time security checks. slurp build
does that AND renders. Four codes are render-time only, which is why a file can
validate clean and then fail to build:
Codes the compiler emits
UnexpectedToken
The default parse and lex failure. Also what a construct that LOOKS like a block tag
gets when no parser supports it.
if, each, match,
fetch, repeat, try, slot, layout, head, sections and blocks.
{error} and {loading} are branch markers, legal only inside {fetch} or
{try}. {with} does not exist in any form; write the full path instead.
The same code covers {case} inside {match}, every operator the language does not
have (===, ??, ?., in, **, typeof, the bitwise set), and a stray { in
ordinary text, which the lexer reads as the start of an interpolation.
UnclosedBlock
A block tag was opened and never closed, or an expression was left open.
{/empty}. Which tags need a close and which do not:
InvalidFrontmatter
A malformed frontmatter directive or schema declaration. This is by far the largest
family: a bad setting kind, a select default outside its own options, a duplicate
setting key or block type, a section with no name, a max below 1, an empty
@theme(), or any @target other than @theme.
text, richtext, color, image, icon,
link, select, number or toggle, and a select default must appear in its
own option list.
Unknown frontmatter STATEMENTS are silently skipped, not reported. This code fires
only on a malformed KNOWN one. A misspelled directive produces no diagnostic at
all.
SecretEnvInTemplate
A template read env.SLURP_SECRET_something, in dotted or subscript form. Also
fires for env[key] with a key that is not a compile-time constant, because such a
key could resolve to a secret name.
MiddlewareScopeViolation
Either request.* was used in a file that is not compiled as middleware, or a file
that IS middleware read a path root other than request, env or loop.
request.* is middleware-only. In an ordinary page, take what you need
from the request on the server and pass it through the render context:
--middleware <DIR>. A correct
middleware file reports this error until you pass that flag.
RedirectOutsideMiddleware
A {redirect} or {next} appeared in a file that is not compiled as middleware.
UnsafeScriptInterpolation
Two distinct rules share this code, plus two development-mode advisories.
Rule 1: an expression in a <script> body with neither | js nor | json.
| json for a bare value, or | js when it sits
inside a string literal you wrote:
| unsafe_js does NOT satisfy the rule. The raw hatch in a script body is
{html expr}.
Rule 2: a | js slot in a JavaScript-evaluated attribute that lands in statement
or expression position rather than inside a quoted string.
| json:
HTML entity escaping does not protect a script context. A raw-text element reaches
the JavaScript engine without character references being decoded, so the ordinary
text escaping is inert there.Note also that a JavaScript template literal cannot be written in a
<script>
body at all, because Slurp claims the ${ sequence itself. Build the string by
concatenation.style value slot, and an undeclared slot in a
JavaScript-evaluated attribute. Both are silent in a production render, which is
what slurp build always uses.
JsTemplateLiteralInAttribute
Severity: warning. A quoted HTML attribute value contains a JavaScript template
literal whose ${ } slot Slurp will interpolate itself, against the SERVER render
context rather than the browser one.
UnknownFilter
A filter name that is in neither table. The value table and the loop table are
disjoint, so using one where the other belongs also lands here.
${ }: upper, lower, currency, truncate,
fixed, date, default, plural, int, float, js, json, unsafe_js.
Loop filters, usable ONLY in an {each} header: limit, sort, reverse,
filter. See Filters.
This is a RENDER-time error, so slurp validate will not report it. The renderer
passes the value through unfiltered alongside the diagnostic, so the render itself
completes, but the CLI treats the diagnostic as an error and emits no file.
InvalidFilterArgs
A required filter argument was missing, or could not be read as a literal. In
practice this is limit() and filter().
Filter 'limit' requires at least 1 argument(s) instead.
Fix. Supply the argument as a literal:
default is the only exception.
MissingImageSrc
An <Image> was written with no src prop.
src:
width defaults to 800 and height to 600, and
both accept a literal such as width={400} as well as a context value. height is
only used for the <img> attribute and is never sent to the image service.
IterationLimitExceeded
A budget was exhausted. Severity is mixed: two of the budgets are errors and the
rest are warnings.
CircularImport
Two templates import each other, directly or through a chain, or the chain exceeds
128 links.
Fix. Break the cycle by extracting the shared part into a third file that
neither of the two imports back.
Only reachable through the virtual-files compile path used by an embedding host.
Neither
slurp build nor slurp validate detects it, because neither builds a
cross-file import graph.Codes declared but never emitted
These 8 are in theErrorCode enum for host integrations to reuse. The compiler
never produces them, and the note for each says what happens instead, because in
several cases the condition IS detected and handled another way.
Conditions that produce no error at all
Slurp is total and tolerant. These are the failures with no diagnostic anywhere.
Several of these are caught by the linter in the MCP server even though the compiler
says nothing. Build with
--verbose while developing, and read
Common mistakes, which collects the silent
failures with the fix for each.