{"record":{"id":"e6d0433140db2e96","repo":"cakephp/cakephp","slug":"missing-dependency-controllerfactory","errorCode":null,"errorMessage":"missing_dependency","messagePattern":"missing_dependency","errorType":"validation","errorClass":"InvalidParameterException","httpStatus":null,"severity":"error","filePath":"src/Controller/ControllerFactory.php","lineNumber":221,"sourceCode":"                    $resolved[] = $this->container->get($typeName);\n                    continue;\n                }\n\n                // Use passedParams as a source of typed dependencies.\n                // The accepted types for passedParams was never defined and userland code relies on that.\n                if ($passedParams && $passedParams[0] instanceof $typeName) {\n                    $resolved[] = array_shift($passedParams);\n                    continue;\n                }\n\n                // Add default value if provided\n                // Do not allow positional arguments for classes\n                if ($parameter->isDefaultValueAvailable()) {\n                    $resolved[] = $parameter->getDefaultValue();\n                    continue;\n                }\n\n                throw new InvalidParameterException([\n                    'template' => 'missing_dependency',\n                    'parameter' => $parameter->getName(),\n                    'type' => $typeName,\n                    'controller' => $this->controller->getName(),\n                    'action' => $this->controller->getRequest()->getParam('action'),\n                    'prefix' => $this->controller->getRequest()->getParam('prefix'),\n                    'plugin' => $this->controller->getRequest()->getParam('plugin'),\n                ]);\n            }\n\n            // Use any passed params as positional arguments\n            if ($passedParams) {\n                $argument = array_shift($passedParams);\n                if (is_string($argument) && $type instanceof ReflectionNamedType) {\n                    $typedArgument = $this->coerceStringToType($argument, $type);\n\n                    if ($typedArgument === null) {\n                        throw new InvalidParameterException([","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/cakephp/cakephp/blob/1128eba9b09f1946df684811350e26f2cef68fac/src/Controller/ControllerFactory.php#L203-L239","documentation":"InvalidParameterException with template 'missing_dependency' is thrown by ControllerFactory::getActionArgs() when an action method's parameter is type-hinted to a class/interface that the service container cannot resolve and the parameter has no default value. CakePHP refuses to call the action with a null for a required class dependency.","triggerScenarios":"An action signature like myAction(MyService $service) where MyService is not registered/bound in the DI container; requesting positional-argument resolution for a class-typed parameter that has no default value and no matching container binding.","commonSituations":"Adding a new injected dependency to an action without registering it with the Application's services; typo in the type-hint namespace; interface binding missing after a refactor.","solutions":["Register the dependency in the DI container (Application::services() add/bind the class or interface)","Add a default value to the action parameter if it is optional: myAction(?MyService $service = null)","Verify the type-hint's fully-qualified class name/import is correct","If it should be a request scalar, change the hint to a scalar type (string/int) so it resolves from route/passed params"],"exampleFix":"// before\nclass ServicesController\n{\n    public function index(PaymentGateway $gateway) { ... } // not registered\n}\n// after: in Application::services()\n$container->add(PaymentGatewayInterface::class, StripeGateway::class);\n// or give the parameter a default\npublic function index(?PaymentGateway $gateway = null) { ... }","handlingStrategy":"try-catch","validationCode":"use Cake\\Core\\Container;\n// ensure the dependency is resolvable before dispatch\nif (!$container->has(MyService::class)) {\n    $container->add(MyService::class);\n}","typeGuard":"function resolvable(Cake\\Core\\ContainerInterface $c, string $type): bool\n{\n    return class_exists($type) || interface_exists($type) ? $c->has($type) : false;\n}","tryCatchPattern":"try {\n    $args = $factory->getActionArgs($reflection, $request);\n} catch (Cake\\Controller\\Exception\\InvalidParameterException $e) {\n    if ($e->getMessage() === 'missing_dependency') {\n        error_log('Unregistered DI dependency: ' . $e->getAttribute('parameter'));\n    }\n    return new Cake\\Http\\Response(['status' => 500]);\n}","preventionTips":["Register every class/interface injected into controller actions in Application::services()","Use interface bindings so implementation swaps don't break resolution","Add a smoke test that dispatches each action to catch unresolvable hints","Keep imports/FQCNs of type-hints correct after refactors"],"tags":["dependency-injection","controller","cakephp"],"backgroundTag":"missing-dependency","analyzedSha":"1128eba9b09f1946df684811350e26f2cef68fac","analyzedAt":"2026-09-12T12:07:00.388Z","contentChangedAt":"2026-09-12T12:07:00.388Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}