yiisoft/yii2 · error · InvalidCallException

Unable to resolve view file for view '$view': no active view

Error message

Unable to resolve view file for view '$view': no active view context.

What it means

Thrown by yii\base\View::getViewFile() for a relative view name (no leading slash or alias) when none of the resolution anchors exist: the passed $context does not implement yii\base\ViewContextInterface, and there is no currently requested view file (getRequestedViewFile() returns false, i.e. the render is not happening from inside another view). Relative names can only be resolved against one of those two anchors, so the call fails.

Source

Thrown at framework/base/View.php:191

        if (strncmp($view, '@', 1) === 0) {
            // e.g. "@app/views/main"
            $file = Yii::getAlias($view);
        } elseif (strncmp($view, '//', 2) === 0) {
            // e.g. "//layouts/main"
            $file = Yii::$app->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
        } elseif (strncmp($view, '/', 1) === 0) {
            // e.g. "/site/index"
            if (Yii::$app->controller !== null) {
                $file = Yii::$app->controller->module->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
            } else {
                throw new InvalidCallException("Unable to locate view file for view '$view': no active controller.");
            }
        } elseif ($context instanceof ViewContextInterface) {
            $file = $context->getViewPath() . DIRECTORY_SEPARATOR . $view;
        } elseif (($currentViewFile = $this->getRequestedViewFile()) !== false) {
            $file = dirname($currentViewFile) . DIRECTORY_SEPARATOR . $view;
        } else {
            throw new InvalidCallException("Unable to resolve view file for view '$view': no active view context.");
        }

        if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
            return $file;
        }
        $path = $file . '.' . $this->defaultExtension;
        if ($this->defaultExtension !== 'php' && !is_file($path)) {
            $path = $file . '.php';
        }

        return $path;
    }

    /**
     * Renders a view file.
     *
     * If [[theme]] is enabled (not null), it will try to render the themed version of the view file as long
     * as it is available.

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Pass a context implementing ViewContextInterface, e.g. the controller or a dedicated renderer class with getViewPath() — the mailer components (yii\mail\BaseMailer) already do this via viewPath.
  2. Switch to an absolute alias path: render('@app/views/emails/welcome', ...).
  3. When rendering from inside another view, keep using $this->render() (the View context is inherited) instead of fetching a fresh view component.

Example fix

// before
class WelcomeService {
    public function send($user) {
        return Yii::$app->view->render('welcome', ['user' => $user]); // no context, not inside a view -> throws
    }
}

// after
class WelcomeService implements \yii\base\ViewContextInterface {
    public function send($user) {
        return Yii::$app->view->render('welcome', ['user' => $user], $this);
    }
    public function getViewPath() { return '@app/views/emails'; }
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a resolution anchor exists before rendering a relative view name
$anchored = strncmp($view, '@', 1) === 0
    || strncmp($view, '//', 2) === 0
    || strncmp($view, '/', 1) === 0 && Yii::$app->controller !== null
    || $context instanceof \yii\base\ViewContextInterface
    || Yii::$app->view->getRequestedViewFile() !== false;
if (!$anchored) {
    $view = '@app/views/' . $view; // or pass a context: render($view, $params, $this)
}

Type guard

function providesViewPath($context): bool
{
    return $context instanceof \yii\base\ViewContextInterface;
}

Prevention

When it happens

Trigger: Calling Yii::$app->view->render('welcome') with null or a non-context $context outside of a view render chain (console, queue job, controller-less web entry); calling View::render() from a widget whose context is a plain object; rendering a relative layout name from code that is not itself a view.

Common situations: Console commands or mailer code rendering relative view names copied from view files; refactoring a render call out of a view into a service class, losing the implicit 'current view file' anchor; passing the model as $context instead of an object with getViewPath().

Related errors


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/1b56cb5432b0faaa. Report an issue: GitHub.