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

  1. Pass every required argument: {{ avatar('/img/a.png', 'Profile') }} or named: {{ avatar(url='/img/a.png', alt='Profile') }}.
  2. Give the parameter a default in the definition so old callers keep working: {% macro avatar(url, alt='Image') %}.
  3. 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

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


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/fc69271ff7cac365. Report an issue: GitHub.