{"record":{"id":"eb88103110356956","repo":"yiisoft/yii2","slug":"reference-id-refers-to-a-get-class-component","errorCode":null,"errorMessage":"\"$reference->id\" refers to a get_class($component) component. $type is expected.","messagePattern":"\"\\$reference->id\" refers to a get_class\\(\\$component\\) component\\. \\$type is expected\\.","errorType":"exception","errorClass":"InvalidConfigException","httpStatus":null,"severity":"error","filePath":"framework/di/Instance.php","lineNumber":162,"sourceCode":"        }\n\n        if (is_string($reference)) {\n            $reference = new static($reference);\n        } elseif ($type === null || $reference instanceof $type) {\n            return $reference;\n        }\n\n        if ($reference instanceof self) {\n            try {\n                $component = $reference->get($container);\n            } catch (\\ReflectionException $e) {\n                throw new InvalidConfigException('Failed to instantiate component or class \"' . $reference->id . '\".', 0, $e);\n            }\n            if ($type === null || $component instanceof $type) {\n                return $component;\n            }\n\n            throw new InvalidConfigException('\"' . $reference->id . '\" refers to a ' . get_class($component) . \" component. $type is expected.\");\n        }\n\n        $valueType = is_object($reference) ? get_class($reference) : gettype($reference);\n        throw new InvalidConfigException(\"Invalid data type: $valueType. $type is expected.\");\n    }\n\n    /**\n     * Returns the actual object referenced by this Instance object.\n     * @param ServiceLocator|Container|null $container the container used to locate the referenced object.\n     * If null, the method will first try `Yii::$app` then `Yii::$container`.\n     * @return object|null the actual object referenced by this Instance object.\n     */\n    public function get($container = null)\n    {\n        try {\n            if ($container) {\n                return $container->get($this->id);\n            }","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/di/Instance.php#L144-L180","documentation":"After yii\\di\\Instance::ensure() resolved an Instance reference (an ID like 'cache') through the container, the returned object was not an instance of the expected $type, so it throws '\"<id>\" refers to a <actual class> component. <type> is expected.' This is the component-ID variant of the type check: the reference resolved fine, but the registered definition points at an incompatible class.","triggerScenarios":"Instance::ensure('cache', 'app\\components\\CacheInterface') when 'cache' is configured as yii\\caching\\FileCache which does not implement that interface; code declaring Instance::of('user')->get() and passing it where a custom User subclass is required.","commonSituations":"Overriding a core component ('user', 'db', 'mailer') with a custom class, then passing it to code that requires a stricter type; introducing an interface expectation after the component was already registered with the framework default.","solutions":["Change the component registration so the ID maps to a class implementing/extending the expected type.","Relax the expectation: pass a parent class/interface that the registered class satisfies, or null to skip checking.","Register the custom object under a new ID and reference that ID where the specific type is needed.","Make the custom class implement the required interface."],"exampleFix":"// before\n$cache = Instance::ensure('cache', app\\components\\CacheInterface::class);\n// 'cache' is configured as yii\\caching\\FileCache\n\n// after\n'components' => [\n    'cache' => ['class' => app\\components\\RedisCache::class], // implements CacheInterface\n],","handlingStrategy":"type-guard","validationCode":"$component = Yii::$app->get('cache'); // resolve the ID first\nif (!$component instanceof app\\components\\CacheInterface) {\n    throw new \\InvalidArgumentException(\"'cache' must implement CacheInterface, got \" . get_class($component));\n}\n// now safe to use; equivalent Instance::ensure() call will not throw","typeGuard":"/** True when the component registered under $id satisfies $type. */\nfunction componentSatisfies(string $id, string $type): bool\n{\n    if (!Yii::$app->has($id)) {\n        return false;\n    }\n    return Yii::$app->get($id) instanceof $type;\n}","tryCatchPattern":"try {\n    $cache = \\yii\\di\\Instance::ensure('cache', app\\components\\CacheInterface::class);\n} catch (\\yii\\base\\InvalidConfigException $e) {\n    // message states which class 'cache' actually is - fix the registration, not the call site\n    Yii::error($e->getMessage(), 'config');\n    throw;\n}","preventionTips":["When overriding core components, keep the interface contract of the original.","Assert component types once in bootstrap (instanceof on Yii::$app->get(...)) to fail at deploy, not at request time.","Document the required type next to every property documented with Instance::ensure usage."],"tags":["yii2","dependency-injection","instance","type-mismatch","config"],"backgroundTag":"di-type-mismatch","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}