phalcon/cphalcon · error · Phalcon\Mvc\View\Exceptions\InvalidViewsDirType

Views directory must be a string or an array

Error message

Views directory must be a string or an array

What it means

View::setViewsDir() accepts exactly a string (single directory) or an array of directories (multi-path views), and throws InvalidViewsDirType otherwise (phalcon/Mvc/View.zep:1125). Any other type — null, int, bool, object — cannot be resolved to a filesystem path, so the view renderer refuses it immediately instead of failing later at render time.

Source

Thrown at phalcon/Mvc/View.zep:1125

        if merge {
            let this->viewParams = array_merge(this->viewParams, params);
        } else {
            let this->viewParams = params;
        }

        return this;
    }

    /**
     * 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;
        }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Ensure the value is a string path with a trailing directory separator, e.g. app/views/
  2. If the key may be missing, default it: $view->setViewsDir($config->path('application.viewsDir', APP_PATH . '/views/'))
  3. Fail fast at bootstrap with your own check if viewsDir is a hard requirement

Example fix

// before
$view->setViewsDir($config->application->viewsDir); // null when key absent

// after
$view->setViewsDir($config->path('application.viewsDir', dirname(__DIR__) . '/views/'));
Defensive patterns

Strategy: type-guard

Validate before calling

if (!is_string($viewsDir) && !is_array($viewsDir)) {
    throw new \InvalidArgumentException('viewsDir must be a string or array of strings');
}

Type guard

function acceptsViewsDir(mixed $dir): bool
{
    return is_string($dir) || (is_array($dir) && array_filter($dir, 'is_string') === array_values($dir));
}

Prevention

When it happens

Trigger: $view->setViewsDir($config->application->viewsDir) when the config key is absent so null is passed; setViewsDir(0) or setViewsDir(false); passing an object (e.g. a Config object) instead of ->viewsDir string.

Common situations: Missing 'viewsDir' key in config.php (classic Phalcon INI/PHP config bootstrap); environment-specific config where one env lacks the key; refactoring config structure while view setup code still reads the old path.

Related errors


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