yiisoft/yii2 · error · InvalidConfigException
The configuration for the "$id" component must contain a "cl
Error message
The configuration for the "$id" component must contain a "class" element.
What it means
yii\di\ServiceLocator::setComponent()/set() only accepts an object, a callable, or a configuration array - and a configuration array must carry the concrete class to instantiate, given as 'class' (or '__class', which is normalized to 'class'). When the array has neither key, the locator cannot know what to build and throws this InvalidConfigException.
Source
Thrown at framework/di/ServiceLocator.php:210
if ($definition === null) {
unset($this->_definitions[$id]);
return;
}
if (is_object($definition) || is_callable($definition, true)) {
// an object, a class name, or a PHP callable
$this->_definitions[$id] = $definition;
} elseif (is_array($definition)) {
// a configuration array
if (isset($definition['__class'])) {
$this->_definitions[$id] = $definition;
$this->_definitions[$id]['class'] = $definition['__class'];
unset($this->_definitions[$id]['__class']);
} elseif (isset($definition['class'])) {
$this->_definitions[$id] = $definition;
} else {
throw new InvalidConfigException("The configuration for the \"$id\" component must contain a \"class\" element.");
}
} else {
throw new InvalidConfigException("Unexpected configuration type for the \"$id\" component: " . gettype($definition));
}
}
/**
* Removes the component from the locator.
* @param string $id the component ID
*/
public function clear($id)
{
unset($this->_definitions[$id], $this->_components[$id]);
}
/**
* Returns the list of the component definitions or the loaded component instances.
* @param bool $returnDefinitions whether to return component definitions instead of the loaded component instances.View on GitHub (pinned to 66f00d18a2)
Solutions
- Add the class key: ['class' => yii\swiftmailer\Mailer::class, ...options].
- Use '__class' only if you need Yii 3-style config; the locator normalizes it to 'class'.
- Check config merge order so the file containing 'class' is loaded and not overwritten wholesale.
- Verify the key spelling is exactly lowercase 'class'.
Example fix
// before
Yii::$app->setComponents([
'mailer' => ['transport' => 'smtp'], // no class
]);
// after
Yii::$app->setComponents([
'mailer' => ['class' => yii\swiftmailer\Mailer::class, 'transport' => 'smtp'],
]); Defensive patterns
Strategy: validation
Validate before calling
foreach ($components as $id => $definition) {
if (is_array($definition) && !isset($definition['class'], $definition['__class'])) {
throw new \InvalidArgumentException("Component '$id' config must contain a 'class' element.");
}
}
Yii::$app->setComponents($components); Type guard
/** True when the definition can be registered with setComponents(). */
function isRegistrableDefinition($definition): bool
{
if (is_object($definition) || is_callable($definition, true)) {
return true;
}
return is_array($definition) && (isset($definition['class']) || isset($definition['__class']));
} Try / catch
try {
Yii::$app->setComponents($config['components']);
} catch (\yii\base\InvalidConfigException $e) {
// message names the offending component ID - fail fast at boot with a clear config error
Yii::error($e->getMessage(), 'config');
throw;
} Prevention
- Always author component config starting from 'class' => TargetClass::class.
- Validate merged config arrays (class key present) in a pre-deploy check.
- Remember per-environment overrides must merge (ArrayHelper::merge) with a base that carries 'class', not replace it.
- Use exactly the lowercase key 'class' (or '__class'); 'Class'/'className' are silently ignored.
When it happens
Trigger: Yii::$app->setComponents(['mailer' => ['transport' => 'smtp']]) - options without 'class'; passing a plain settings array (['host' => ..., 'port' => ...]) from env files straight into setComponents(); merging configs where the entry carrying 'class' gets overwritten.
Common situations: Config assembled from multiple files/env sources where the 'class' key is lost; overriding a component with only its options (correct in per-environment overrides only when merged with a base that has 'class'); typos like 'Class' or 'className' instead of 'class'.
Related errors
- Unknown component ID: $id
- Unexpected configuration type for the "$id" component: getty
- Invalid validation rule: a rule must specify both attribute
- The directory does not exist: $path
- {cipher} is not an allowed cipher
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/7737c184eb201f44.
Report an issue: GitHub.