yiisoft/yii2 · error · InvalidConfigException
Invalid data type: $class. $type is expected.
Error message
Invalid data type: $class. $type is expected.
What it means
yii\di\Instance::ensure() resolved the given array configuration through the container, but the resulting object is not an instance of the expected $type. ensure() is Yii's mechanism for accepting either a component ID, a config array, or an object wherever a component of a certain class/interface is required; when the array's '__class'/'class' entry produces an incompatible object, it throws InvalidConfigException naming the class it got and the type it expected.
Source
Thrown at framework/di/Instance.php:141
if (is_array($reference)) {
if (!$container instanceof Container) {
$container = Yii::$container;
}
if (isset($reference['__class'])) {
$class = $reference['__class'];
unset($reference['__class'], $reference['class']);
} elseif (isset($reference['class'])) {
$class = $reference['class'];
unset($reference['class']);
} else {
$class = $type;
}
$component = $container->get($class, [], $reference);
if ($type === null || $component instanceof $type) {
return $component;
}
throw new InvalidConfigException('Invalid data type: ' . $class . '. ' . $type . ' is expected.');
} elseif (empty($reference)) {
throw new InvalidConfigException('The required component is not specified.');
}
if (is_string($reference)) {
$reference = new static($reference);
} elseif ($type === null || $reference instanceof $type) {
return $reference;
}
if ($reference instanceof self) {
try {
$component = $reference->get($container);
} catch (\ReflectionException $e) {
throw new InvalidConfigException('Failed to instantiate component or class "' . $reference->id . '".', 0, $e);
}
if ($type === null || $component instanceof $type) {
return $component;View on GitHub (pinned to 66f00d18a2)
Solutions
- Set '__class'/'class' to a class that implements/subclasses the expected type (e.g. a Mailer implementation for a mailer slot).
- If you have a custom implementation, make it extend/implement the expected base class or interface.
- Register the object under a component ID and pass the ID string instead of an inline array, after fixing the registration.
- Remove an overly specific Instance::ensure() type constraint if any implementation is actually acceptable.
Example fix
// before - property expects yii\mail\MailerInterface 'mailer' => ['__class' => app\components\SmsSender::class], // after 'mailer' => ['__class' => yii\swiftmailer\Mailer::class], // or make SmsSender implement yii\mail\MailerInterface
Defensive patterns
Strategy: type-guard
Validate before calling
// before passing an inline config to a typed slot
if (is_array($config) && isset($config['class']) && !is_subclass_of($config['class'], $expectedType)) {
throw new \InvalidArgumentException('Configured class does not satisfy ' . $expectedType);
}
$component = \yii\di\Instance::ensure($config, $expectedType); Type guard
/** Narrows a mixed value to something Instance::ensure() can accept for $type. */
function isComponentReference($value, string $type): bool
{
if ($value instanceof $type) {
return true;
}
if (is_string($value)) {
return Yii::$app->has($value) || class_exists($value);
}
if (is_array($value)) {
$class = $value['__class'] ?? $value['class'] ?? null;
return $class !== null && is_a($class, $type, true);
}
return false;
} Try / catch
use yii\base\InvalidConfigException;
try {
$mailer = \yii\di\Instance::ensure($config, \yii\mail\MailerInterface::class);
} catch (InvalidConfigException $e) {
// message names the class produced vs expected - surface as a boot-time config error
Yii::error($e->getMessage(), 'config');
throw;
} Prevention
- Make custom component implementations extend/implement the documented base type.
- Add a startup assertion that is_a($config['class'], RequiredType::class, true) for critical components.
- Keep an interface per component slot and validate config in a bootstrap check on deploy.
- Never copy component config between slots without checking the expected type in the target property's PHPDoc.
When it happens
Trigger: Passing an inline config array to a typed component slot, e.g. 'mailer' => ['__class' => app\components\SmsSender::class] where the property is documented/typed as yii\mail\MailerInterface and validated via Instance::ensure($value, MailerInterface::class).
Common situations: Configuring framework components inline in config/web.php with the wrong class; swapping a component implementation that does not implement the required interface (custom cache, custom mailer); copy-pasted config between components with different base types.
Related errors
- "$reference->id" refers to a get_class($component) component
- The required component is not specified.
- Failed to instantiate component or class "$reference->id".
- Invalid data type: $valueType. $type is expected.
- Failed to instantiate class "Instance". Required parameter "
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/5b138c2ef401edec.
Report an issue: GitHub.