phalcon/cphalcon · error · Phalcon\Mvc\View\Exceptions\ViewsDirItemMustBeString
Views directory item must be a string
Error message
Views directory item must be a string
What it means
When setViewsDir() receives an array, Phalcon iterates it and each element must itself be a string path; a non-string element (null, nested array, int) triggers ViewsDirItemMustBeString at phalcon/Mvc/View.zep:1135. The array form exists to let getViewsDirs()/render check multiple view roots in order (e.g. theme dir + app dir), so every entry must be a usable path.
Source
Thrown at phalcon/Mvc/View.zep:1135
* Sets the views directory. Depending of your platform,
* always add a trailing slash or backslash
*/
public function setViewsDir(var viewsDir) -> <static>
{
var position, directory, newViewsDir;
if typeof viewsDir !== "string" && typeof viewsDir !== "array" {
throw new InvalidViewsDirType();
}
if typeof viewsDir == "string" {
let this->viewsDirs = this->toDirSeparator(viewsDir);
} else {
let newViewsDir = [];
for position, directory in viewsDir {
if typeof directory != "string" {
throw new ViewsDirItemMustBeString();
}
let newViewsDir[position] = this->toDirSeparator(directory);
}
let this->viewsDirs = newViewsDir;
}
return this;
}
/**
* Starts rendering process enabling the output buffering
*/
public function start() -> <static>
{
ob_start();
View on GitHub (pinned to b7419de9cd)
Solutions
- array_filter($dirs, 'is_string') (or filter out nulls) before passing the array
- Default optional entries to '' or omit them entirely
- Validate each entry with is_string() when building the list dynamically
Example fix
// before $view->setViewsDir([$config->themePath, $config->fallbackThemePath]); // fallback null // after $dirs = array_filter([$config->themePath, $config->fallbackThemePath], 'is_string'); $view->setViewsDir(array_values($dirs));
Defensive patterns
Strategy: validation
Validate before calling
$dirs = array_values(array_filter($dirs, 'is_string'));
if ($dirs === []) {
throw new \InvalidArgumentException('At least one string views directory is required');
} Type guard
function isStringList(mixed $list): bool
{
return is_array($list) && array_reduce($list, fn($ok, $v) => $ok && is_string($v), true);
} Prevention
- Filter optional directory entries before setViewsDir()
- Keep multi-dir lists flat — no nested arrays
- Build views-dir lists from typed config schemas
When it happens
Trigger: setViewsDir([$themesDir . '/dark', null]) where one slot is an unset variable; setViewsDir(json_decode($json, true)) where a value decoded as int/array; array_merge producing nested arrays.
Common situations: Multi-theme setups assembling directory lists dynamically; config arrays with optional directories that end up null; a views array built from a JSON/YAML source with mixed types.
Related errors
- Views directory must be a string or an array
- View '{viewPath}' was not found in any of the views director
- A dependency injection container is required to access appli
- Invalid template engine registration for extension: {extensi
- {message}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/25bd3732ddacee86.
Report an issue: GitHub.