phalcon/cphalcon · error · Phalcon\Mvc\View\Engine\Volt\Exceptions\InvalidOptionType
'extension' must be a string
Error message
'extension' must be a string
What it means
The Volt 'extension' option (deprecated alias 'compiledExtension') sets the file extension appended to compiled templates — default '.php' — and must be a string; any other type throws InvalidOptionType('extension', 'string') at phalcon/Mvc/View/Engine/Volt/Compiler.zep:406. Note this is the compiled-file extension, not the template source extension.
Source
Thrown at phalcon/Mvc/View/Engine/Volt/Compiler.zep:406
throw new InvalidOptionType("separator", "string");
}
/**
* By default the compile extension is .php
*/
if !fetch compiledExtension, options["extension"] {
if fetch compiledExtension, options["compiledExtension"] {
trigger_error(
"The 'compiledExtension' option is deprecated. Use 'extension' instead.",
E_USER_DEPRECATED
);
} else {
let compiledExtension = ".php";
}
}
if unlikely typeof compiledExtension != "string" {
throw new InvalidOptionType("extension", "string");
}
/**
* Stat option assumes the compilation of the file
*/
if !fetch stat, options["stat"] {
let stat = true;
}
/**
* Check if there is a compiled path
*/
if typeof compiledPath == "string" {
/**
* Calculate the template realpath's
*/
if !empty compiledPath {
/**View on GitHub (pinned to b7419de9cd)
Solutions
- Omit the key to keep the '.php' default, or pass an explicit string including the leading dot
- Cast where the value may be numeric/nullable: 'extension' => (string) $value
- Sanitize the entire options array (always/prefix/separator/extension/path/stat) in one place before setOptions()
Example fix
// before
$volt->setOptions(['extension' => $config->volt->compiledExtension]); // null
// after
$volt->setOptions(['extension' => (string) $config->path('volt.compiledExtension', '.php')]); Defensive patterns
Strategy: validation
Validate before calling
if (isset($options['extension']) && !is_string($options['extension'])) {
$options['extension'] = (string) $options['extension'];
} Type guard
function isVoltExtensionOptionValid(mixed $ext): bool
{
return !isset($ext) || is_string($ext);
} Prevention
- Remember 'extension' = compiled file extension, default .php
- Cast nullable config values or drop the key
- Sanitize always/prefix/separator/extension/path/stat together
When it happens
Trigger: setOptions(['extension' => '.php']) is fine, but setOptions(['extension' => null]) or an array throws; option arrays built from user/config input without normalization; deprecated 'compiledExtension' key with a non-string value after a Phalcon 5 upgrade.
Common situations: Config-driven Volt options where the key exists but is empty/null; mixing up 'extension' (compiled file) with engine-registration keys like '.volt'; JSON/YAML sources yielding non-string scalars.
Related errors
- 'always' must be a bool value
- 'prefix' must be a string
- 'separator' must be a string
- The extension is not valid
- 'path' closure didn't return a valid string
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/b6fed7a5491451da.
Report an issue: GitHub.