phalcon/cphalcon · error · Phalcon\Mvc\View\Engine\Volt\Exceptions\MacroNotFound
Macro '{name}' does not exist
Error message
Macro '{name}' does not exist What it means
Volt compiles calls to unknown template functions/macros into $this->callMacro($name, $args) on the Volt engine; if the name is not present in the registered macros map, MacroNotFound is thrown (phalcon/Mvc/View/Engine/Volt.zep:65). Macros come from { % macro name() % } definitions compiled from the current (or imported) template, so this error means the macro name was never defined or registered at call time.
Source
Thrown at phalcon/Mvc/View/Engine/Volt.zep:65
/**
* @var array
*/
protected options = [];
/**
* Checks if a macro is defined and calls it
*
* @params string name
* @params array arguments
*
* @return mixed
*/
public function callMacro( string name, array arguments = []) -> var
{
var macro;
if unlikely !fetch macro, this->macros[name] {
throw new MacroNotFound(name);
}
return call_user_func(macro, arguments);
}
/**
* Performs a string conversion
*
* @return string
*/
public function convertEncoding(string text, string from, string to) -> string
{
if unlikely !this->phpFunctionExists("mb_convert_encoding") {
throw new MbstringRequired();
}
return mb_convert_encoding(text, to, from);
}View on GitHub (pinned to b7419de9cd)
Solutions
- Define the macro in the same template above its first use, or import it: {% import 'macros.volt' as m %} then {{ m.formattedPrice(p) }}
- Check for typos between macro definition name and call site
- Clear the compiled Volt cache directory after moving/renaming macros
Example fix
// before (template.volt)
{{ formattedPrice(product.price) }} {# macro never defined/imported #}
// after
{% import 'macros.volt' as m %}
{{ m.formattedPrice(product.price) }} Defensive patterns
Strategy: try-catch
Try / catch
use Phalcon\Mvc\View\Engine\Volt\Exceptions\MacroNotFound;
try {
// template rendering that calls a possibly-missing macro
$html = $view->render('index/index');
} catch (MacroNotFound $e) {
$logger->warning('Missing Volt macro: ' . $e->getMessage());
$html = $view->render('index/fallback');
} Prevention
- Import macro libraries explicitly: {% import 'macros.volt' as m %}
- Keep macro names in one shared template and import it in layouts
- Clear the Volt compiled cache after macro renames
- Prefer plain helpers/functions for logic shared across templates
When it happens
Trigger: Template calls {{ formattedPrice(p) }} but the {% macro formattedPrice %} block is absent or lives in a template that was never imported; a typo between definition and call; macro defined after its use point; stale compiled template referencing a macro removed from the source.
Common situations: Refactoring shared macros into a separate macros.volt and forgetting {{ import('macros.volt') }} or the import alias; compileAlways/stale compiledVolt cache keeping an old macro set; copy-pasting template snippets between projects that rely on project-local macros.
Related errors
- Invalid haystack
- Failed to store metaData to the cache adapter
- Invalid template engine registration for extension: {extensi
- 'mbstring' is required to perform the charset conversion
- The extension is not valid
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/48f7242d56cf9389.
Report an issue: GitHub.