{"record":{"id":"2cdbbd7ac29927ec","repo":"yiisoft/yii2","slug":"unexpected-configuration-type-for-the-id-compon","errorCode":null,"errorMessage":"Unexpected configuration type for the \"$id\" component: gettype($definition)","messagePattern":"Unexpected configuration type for the \"\\$id\" component: gettype\\(\\$definition\\)","errorType":"exception","errorClass":"InvalidConfigException","httpStatus":null,"severity":"error","filePath":"framework/di/ServiceLocator.php","lineNumber":213,"sourceCode":"            return;\n        }\n\n        if (is_object($definition) || is_callable($definition, true)) {\n            // an object, a class name, or a PHP callable\n            $this->_definitions[$id] = $definition;\n        } elseif (is_array($definition)) {\n            // a configuration array\n            if (isset($definition['__class'])) {\n                $this->_definitions[$id] = $definition;\n                $this->_definitions[$id]['class'] = $definition['__class'];\n                unset($this->_definitions[$id]['__class']);\n            } elseif (isset($definition['class'])) {\n                $this->_definitions[$id] = $definition;\n            } else {\n                throw new InvalidConfigException(\"The configuration for the \\\"$id\\\" component must contain a \\\"class\\\" element.\");\n            }\n        } else {\n            throw new InvalidConfigException(\"Unexpected configuration type for the \\\"$id\\\" component: \" . gettype($definition));\n        }\n    }\n\n    /**\n     * Removes the component from the locator.\n     * @param string $id the component ID\n     */\n    public function clear($id)\n    {\n        unset($this->_definitions[$id], $this->_components[$id]);\n    }\n\n    /**\n     * Returns the list of the component definitions or the loaded component instances.\n     * @param bool $returnDefinitions whether to return component definitions instead of the loaded component instances.\n     * @return array the list of the component definitions or the loaded component instances (ID => definition or instance).\n     */\n    public function getComponents($returnDefinitions = true)","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/di/ServiceLocator.php#L195-L231","documentation":"The other branch of yii\\di\\ServiceLocator::setComponent()/set(): the definition is neither an object, a valid callable (which includes class-name strings and 'Class::method' syntax), nor an array - i.e. a scalar like an int, bool, float, or non-callable string. The locator enumerates every acceptable type in the message, so any other PHP type is rejected immediately.","triggerScenarios":"Yii::$app->setComponents(['cache' => 3600]) or ['debug' => true]; a definition read from .env/JSON as a scalar; passing a resource or an uncallable string ('some unknown id ') that is not valid callable syntax.","commonSituations":"Env-driven config where a numeric/boolean placeholder was meant to be expanded into a full component config; copy-paste of option values (duration, flags) into the definition slot; degraded config merges collapsing an array to its first scalar.","solutions":["Wrap scalars into a proper definition array with 'class': ['class' => FileCache::class, 'defaultDuration' => 3600].","If the intent was to pass an existing object, instantiate it first; if a callable, ensure the syntax is callable (class string or 'Class::method').","Validate env-derived config before registering components (is_array with a 'class' key).","Fix the config source so it produces structured arrays, not flattened scalars."],"exampleFix":"// before\nYii::$app->setComponents(['cache' => 3600]);\n\n// after\nYii::$app->setComponents([\n    'cache' => ['class' => yii\\caching\\FileCache::class, 'defaultDuration' => 3600],\n]);","handlingStrategy":"validation","validationCode":"if (!is_array($definition) && !is_object($definition) && !is_callable($definition, true)) {\n    throw new \\InvalidArgumentException(\n        'Component definition must be an object, callable, or config array; got ' . gettype($definition)\n    );\n}\nYii::$app->setComponents([$id => $definition]);","typeGuard":"/** Narrows untrusted config values to the types setComponents() accepts. */\nfunction normalizeDefinition($value): array\n{\n    if (is_array($value)) {\n        return $value;\n    }\n    if (is_object($value) || (is_string($value) && class_exists($value))) {\n        return ['class' => $value];\n    }\n    throw new \\UnexpectedValueException('Unsupported component definition type: ' . gettype($value));\n}","tryCatchPattern":"try {\n    Yii::$app->setComponents($config['components']);\n} catch (\\yii\\base\\InvalidConfigException $e) {\n    if (strpos($e->getMessage(), 'Unexpected configuration type') !== false) {\n        // a scalar leaked into config - fix at the source (env loader, JSON schema)\n        throw new \\RuntimeException('Malformed components config', 0, $e);\n    }\n    throw $e;\n}","preventionTips":["Never put raw option values (numbers, booleans) in the definition slot - wrap them in a config array.","Validate env/JSON-derived config with a schema check before registering components.","Unit-test config loading so structural regressions (array collapsed to scalar) fail in CI, not in production."],"tags":["yii2","service-locator","config","component","invalid-type"],"backgroundTag":"invalid-di-configuration","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}