phalcon/cphalcon · error · Phalcon\Mvc\View\Exception
Macro '{name}' was called without parameter: {variableName}
Error message
Macro '{name}' was called without parameter: {variableName} What it means
When the Volt compiler (compileMacro) compiles a macro parameter that has no default value, it emits a `throw new \Phalcon\Mvc\View\Exception("Macro '<name>' was called without parameter: <var>")` directly into the compiled template code (phalcon/Mvc/View/Engine/Volt/Compiler.zep:1110). The error therefore fires at render time, not compile time: calling the macro without that argument (positionally or by name) executes the throw.
Source
Thrown at phalcon/Mvc/View/Engine/Volt/Compiler.zep:1110
/**
* Parameters are always received as an array
*/
let code .= macroName . " = function($__p = null) { ";
for position, parameter in parameters {
let variableName = parameter["variable"];
let code .= "if (isset($__p[" . position . "])) { ";
let code .= "$" . variableName . " = $__p[" . position ."];";
let code .= " } else { ";
let code .= "if (array_key_exists(\"" . variableName . "\", $__p)) { ";
let code .= "$" . variableName . " = $__p[\"" . variableName ."\"];";
let code .= " } else { ";
if likely fetch defaultValue, parameter["default"] {
let code .= "$" . variableName . " = " . this->expression(defaultValue) . ";";
} else {
let code .= " throw new \\Phalcon\\Mvc\\View\\Exception(\"Macro '" . name . "' was called without parameter: " . variableName . "\"); ";
}
let code .= " } } ";
}
let code .= " ?>";
}
/**
* Block statements are allowed
*/
if fetch blockStatements, statement["block_statements"] {
/**
* Process statements block
*/
let code .= this->statementList(blockStatements, extendsMode) . "<?php }; ";
} else {
let code .= "<?php }; ";View on GitHub (pinned to b7419de9cd)
Solutions
- Pass every required argument: {{ avatar('/img/a.png', 'Profile') }} or named: {{ avatar(url='/img/a.png', alt='Profile') }}.
- Give the parameter a default in the definition so old callers keep working: {% macro avatar(url, alt='Image') %}.
- As a safety net, catch Phalcon\Mvc\View\Exception around view rendering to render a friendly error page while you fix callers.
Example fix
{# before #}
{% macro avatar(url, alt) %}<img src="{{ url }}" alt="{{ alt }}">{% endmacro %}
{{ avatar('/img/a.png') }}
{# after #}
{% macro avatar(url, alt='Image') %}<img src="{{ url }}" alt="{{ alt }}">{% endmacro %}
{{ avatar('/img/a.png') }} Defensive patterns
Strategy: validation
Try / catch
try {
$view->render('profile', $params);
} catch (\Phalcon\Mvc\View\Exception $e) {
if (str_contains($e->getMessage(), 'was called without parameter')) {
$logger->error('Volt macro call missing argument: ' . $e->getMessage());
}
throw $e;
} Prevention
- Give every macro parameter a default unless absence is truly exceptional.
- Search the codebase for macro invocations when adding a parameter to a shared macro.
- Remember the failure happens at render time — smoke-render the pages that use each macro in tests.
When it happens
Trigger: {% macro avatar(url, alt) %}...{% endmacro %} then {{ avatar('/img/a.png') }} — 'alt' has no default and is not supplied. Misspelled named arguments also fall through to this branch (array_key_exists on the exact name fails).
Common situations: Adding a new required parameter to a shared macro while some callers are not updated; templates calling macros with named args that got renamed; removing a default during refactor; errors only appear on pages that actually invoke the macro.
Related errors
- View '{viewPath}' was not found in any of the views director
- Invalid template engine registration for extension: {extensi
- Views directory must be a string or an array
- Views directory item must be a string
- A dependency injection container is required to access appli
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/fc69271ff7cac365.
Report an issue: GitHub.