{"record":{"id":"87bb3528565fa00a","repo":"cakephp/cakephp","slug":"loader-s-in-the-chain-is-not-a-valid-callable","errorCode":null,"errorMessage":"Loader `%s` in the chain is not a valid callable.","messagePattern":"Loader `(.+?)` in the chain is not a valid callable\\.","errorType":"exception","errorClass":"Cake\\Core\\Exception\\CakeException","httpStatus":null,"severity":"error","filePath":"src/I18n/ChainMessagesLoader.php","lineNumber":56,"sourceCode":"     * @param array<callable> $loaders List of callables to execute\n     */\n    public function __construct(array $loaders)\n    {\n        $this->_loaders = $loaders;\n    }\n\n    /**\n     * Executes this object returning the translations package as configured in\n     * the chain.\n     *\n     * @return \\Cake\\I18n\\Package\n     * @throws \\Cake\\Core\\Exception\\CakeException if any of the loaders in the chain is not a valid callable\n     */\n    public function __invoke(): Package\n    {\n        foreach ($this->_loaders as $k => $loader) {\n            if (!is_callable($loader)) {\n                throw new CakeException(sprintf(\n                    'Loader `%s` in the chain is not a valid callable.',\n                    $k,\n                ));\n            }\n\n            $package = $loader();\n            if (!$package) {\n                continue;\n            }\n\n            if (!($package instanceof Package)) {\n                throw new CakeException(sprintf(\n                    'Loader `%s` in the chain did not return a valid Package object.',\n                    $k,\n                ));\n            }\n\n            return $package;","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/cakephp/cakephp/blob/1128eba9b09f1946df684811350e26f2cef68fac/src/I18n/ChainMessagesLoader.php#L38-L74","documentation":"ChainMessagesLoader iterates its list of loaders and requires each entry to be a valid callable before invoking it. If an entry is not callable (null, string method not resolvable, non-invokable object, array with missing method), it throws CakeException naming the offending index/key.","triggerScenarios":"Registering a translation loader in the chain as a non-callable value: e.g. a plain string class name lacking __invoke, null where a loader was expected, an array ['Class', 'missingMethod'], or config passing the loader object instead of [$object, 'method'].","commonSituations":"Misconfigured I18n loaders in bootstrap (I18n::config() with a bad loader); typos in method names; dependency not wired so the loader is null; refactor renamed a loader method.","solutions":["Ensure every loader is a Closure, invokable object, or valid [class/object, method] array","Use is_callable($loader) checks (or fn-first class callable syntax) when building the chain in config","Fix the loader registered via I18n::config() / Translator config to point at an existing method","Dump the chain (var_dump($loaders)) and inspect the index named in the message"],"exampleFix":"// before\nI18n::config('default', 'App\\Loader\\MissingLoader'); // string class without __invoke\n// after\nI18n::config('default', function ($name, $locale) {\n    return (new App\\Loader\\MessagesLoader($locale))->loadPackage($name);\n});","handlingStrategy":"validation","validationCode":"$loaders = array_filter($this->_loaders, 'is_callable'); // or assert each before invoking","typeGuard":"function isLoader(mixed $l): bool { return is_callable($l); }","tryCatchPattern":"try { $package = $chainLoader(); } catch (\\Cake\\Core\\Exception\\CakeException $e) { // log bad loader key from message and fall back to default loader }","preventionTips":["Register loaders only as Closures, invokable objects, or valid [object, 'method'] arrays","Type-hint loader params where possible","Sanity-check I18n::config() registrations in tests"],"tags":["php","i18n","translation","callable"],"backgroundTag":"invalid-argument-value","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"}