This page is the canonical index of error codes. To learn how to
throw,catch, and attach data to errors in your own code, see Error handling.
Phel errors are tagged with a stable code like [PHEL001]. The code
survives wording changes, so it is the reliable thing to search for. An error
prints as the code, a message, the source location, a snippet of the offending
code, and often a hint:
[PHEL001] Cannot resolve symbol 'maap'. Did you mean 'map'?
in src/app.phel:12
Codes are grouped by the stage that raises them. Run phel explain PHEL001
to print the same explanation in the terminal.
Analyzer errors
Raised while analyzing forms: undefined names, wrong arity, type and binding problems. The bulk of day-to-day errors.
PHEL001 : Undefined symbol
A symbol could not be resolved to a definition in the current scope.
Common cause: A typo, a missing (:require ...) for the namespace the symbol lives in, an alias that does not match, or using a binding before it is defined.
Fix: Check the spelling, require the namespace (e.g. (:require phel.string :as str) for str/...), or move the definition above its first use. The error message suggests near matches.
PHEL002 : Arity error
A function was called with the wrong number of arguments.
Common cause: The call site passes more or fewer arguments than any of the function's arities accept.
Fix: Match the call to a declared arity. For variadic functions use & rest in the parameter vector.
PHEL003 : Type error
A form received a value of the wrong type.
Common cause: For example attaching metadata that is not a String, Keyword or Map, or passing a non-collection where a collection is required.
Fix: Pass the type the form expects. The message names the value it got.
PHEL004 : Duplicate definition
def was used somewhere it is not allowed.
Common cause: def defines a top-level var, so it cannot appear nested inside a function body or another expression.
Fix: Move the def to the top level of the namespace. For function-local values use let.
PHEL005 : Macro expansion error
A macro threw while expanding.
Common cause: The macro received arguments it did not expect, or its own body raised during expansion.
Fix: Check the arguments at the call site and inspect the expansion with (macroexpand '(your-form ...)).
Learn more: Macros.
PHEL006 : Inline expansion error
An inline-expanded function failed to expand.
Common cause: A function declared with an :inline implementation produced an invalid expansion for the given call.
Fix: Call the function within the shape its :inline definition supports, or report it upstream if it is a core function.
PHEL007 : Invalid special form
A special form was written in an invalid shape.
Common cause: A core form such as if, let, fn, do or quote was given the wrong structure (missing or extra parts).
Fix: Match the form's grammar, e.g. (if test then else?), (let [bindings*] body*).
PHEL008 : Binding error
A binding vector is invalid.
Common cause: An odd number of binding forms in let/loop, or a binding target that cannot be destructured.
Fix: Provide an even number of name value pairs and use valid destructuring targets (symbols, vectors, maps).
Learn more: Destructuring, Global and local bindings.
PHEL009 : Interface error
An interface or protocol definition (or its implementation) is invalid.
Common cause: A malformed definterface/defprotocol, or trying to implement a defprotocol inline in defstruct (only definterface can be implemented inline).
Fix: Use definterface for inline implementation, or defprotocol plus extend-type per struct.
Learn more: Interfaces.
PHEL010 : Recur error
recur was used incorrectly.
Common cause: recur appeared outside a loop/fn tail position, or with an argument count that does not match the recursion point.
Fix: Use recur only in tail position, with as many arguments as the enclosing loop/fn binds.
Learn more: Functions and recursion.
PHEL011 : Not callable
A value that is not a function was called.
Common cause: A non-callable value (a number, string, keyword used wrongly) sits in the head position of a list, often an extra pair of parentheses.
Fix: Remove the stray parentheses, or put a function in the call position.
PHEL012 : Superseded form
A form Phel now says another way was used as source.
Common cause: php/new, php/->, php/:: or set-var was written by hand. The compiler still emits them, but they are no longer accepted in source.
Fix: Use the replacement the message names: (new \Foo arg), (.method obj arg) / (.-field obj), (\Foo/method arg) / \Foo/CONST, and (alter-var-root (var v) f).
Learn more: PHP interop.
PHEL013 : Unresolved refer
A :refer in an ns form names something the required namespace does not define.
Common cause: A typo in the referred name, or a name the namespace keeps private (defn-, def-). Phel checks it when the required namespace is already loaded, which it is for every file a run, test or build loads.
Fix: Check the spelling against the namespace, or drop the name from the :refer vector.
Learn more: Namespaces.
PHEL014 : Missing namespace
A (:require ...) names a namespace Phel cannot find.
Common cause: No source file on the searched directories declares it, it is not loaded, and Phel does not ship it. Usually a typo, or a file outside the configured source directories. The error note lists the directories searched.
Fix: Check the spelling against the ns form of the file you mean, or add its directory to the src, test or vendor dirs.
Learn more: Namespaces, Configuration.
Parser errors
Raised while parsing tokens into forms, almost always an unbalanced or unterminated bracket.
PHEL100 : Unterminated list
A list was not closed.
Common cause: A missing ).
Fix: Balance the parentheses. Editor rainbow-brackets or phel format help spot it.
PHEL101 : Unterminated vector
A vector was not closed.
Common cause: A missing ].
Fix: Balance the brackets.
PHEL102 : Unterminated map
A map was not closed.
Common cause: A missing }, or an odd number of key/value forms.
Fix: Close the brace and ensure every key has a value.
PHEL103 : Unterminated table
A table literal was not closed.
Common cause: A missing closing brace on a @{ ... } table literal.
Fix: Close the table literal.
PHEL110 : Unexpected token
A token appeared where the parser did not expect one.
Common cause: A stray closing bracket, or a reader macro applied to nothing.
Fix: Remove or complete the offending token.
PHEL120 : Parser error
A general parser error.
Common cause: The token stream could not be assembled into valid forms for a reason not covered by a more specific code.
Fix: Check the indicated location for malformed structure.
Reader errors
Raised while reading forms: quote and quasiquote, and map and set literals.
PHEL202 : Invalid splice
A splicing unquote (~@) is invalid.
Common cause: ~@ was used outside a quasiquote, or in a position where a sequence cannot be spliced.
Fix: Use ~@ inside a quasiquote, splicing into a list or vector.
PHEL203 : Duplicate key
A map or set literal holds the same constant key twice, so one entry would be lost.
Common cause: A repeated keyword, string, number, boolean or nil, as in {:a 1 :a 2}. Numbers compare by value, so {1/2 :a 2/4 :b} repeats a key. A symbol or a call is not checked: it keeps the last value, as hash-map and hash-set do.
Fix: Remove the repeated key, or rename the one you meant to be different.
PHEL210 : Reader error
A general reader error.
Common cause: A reader macro could not be read for a reason not covered by a more specific code.
Fix: Check the quote/quasiquote forms at the indicated location.
Lexer errors
Raised while turning source text into tokens: invalid characters or unterminated strings.
PHEL301 : Unterminated string
A string was not closed.
Common cause: A missing closing ", sometimes from an unescaped quote inside the string.
Fix: Close the string and escape interior quotes as \".
PHEL310 : Lexer error
A general lexer error.
Common cause: The source could not be tokenized for a reason not covered by a more specific code.
Fix: Check the indicated location for stray or invalid characters.
Runtime errors
Raised while compiled code runs, not while it compiles: the program was well formed and the values it met were not.
PHEL400 : Runtime not callable
A value that is not a function was called at runtime.
Common cause: The head of the list is a name or an expression the analyzer could not check, and it evaluated to a non-callable value.
Fix: Call a function, or read the value with an accessor such as get, nth or first.
PHEL401 : Runtime arity error
A function was called with the wrong number of arguments at runtime.
Common cause: The callee is a value the analyzer has no arity for, such as a local closure, so the mismatch only surfaces when it runs.
Fix: Pass one argument per declared parameter.
PHEL402 : Runtime type error
A value of the wrong type reached a PHP function or method.
Common cause: Most of these come from php/ interop calls whose callee declares a type the argument does not satisfy.
Fix: Convert the value to the type the callee declares before passing it.
Learn more: PHP interop.
PHEL403 : Index out of bounds
An indexed read asked for a position the collection does not have.
Common cause: nth (and other indexed reads) past the end of a collection. get returns nil instead of throwing.
Fix: Check the index against (count coll), or use get with a default.
PHEL404 : Division by zero
A division or remainder had zero on the right.
Common cause: /, %, rem and php/intdiv all raise it when the divisor is zero.
Fix: Guard the divisor before dividing.