{"record":{"id":"3d33498ce9554905","repo":"phalcon/cphalcon","slug":"auth-context-requires-key-to-be-a-non-empty","errorCode":null,"errorMessage":"Auth {context} requires '{key}' to be a non-empty array","messagePattern":"Auth (.+?) requires '(.+?)' to be a non-empty array","errorType":"exception","errorClass":"Phalcon\\Auth\\Exceptions\\OptionRequiresArray","httpStatus":null,"severity":"error","filePath":"phalcon/Auth/Internal/Options.zep","lineNumber":59,"sourceCode":"\n        /** @var list<array{id?: int|string}&array<string, mixed>> */\n        return array_values(value);\n    }\n\n    /**\n     * @phpstan-param array<string, mixed> $options\n     *\n     * @phpstan-return array<string, mixed>\n     * @throws Exception\n     */\n    public static function requireArray(array options, string key, string context) -> array\n    {\n        var value;\n\n        fetch value, options[key];\n\n        if (typeof value !== \"array\" || empty(value)) {\n            throw new OptionRequiresArray(context, key);\n        }\n\n        return value;\n    }\n\n    /**\n     * @phpstan-param array<string, mixed> $options\n     *\n     * @throws Exception\n     */\n    public static function requireString(array options, string key, string context) -> string\n    {\n        var value;\n\n        fetch value, options[key];\n\n        if (typeof value !== \"string\" || value === \"\") {\n            throw new OptionRequiresString(context, key);","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Auth/Internal/Options.zep#L41-L77","documentation":"Options::requireArray() is the Auth component's validator for array-valued config entries. It fetches the key from the options array and throws OptionRequiresArray (message includes the context, e.g. \"guard 'web'\") when the key is missing, its value is not an array, or the array is empty (empty() also rejects [] and arrays of only null/false). A typical use is ManagerFactory::load() requiring every guard config to have a non-empty 'adapter' array.","triggerScenarios":"Auth config where a guard entry lacks its 'adapter' block: guards: {web: {type: 'session'}}; guards.web.adapter set to a string or null instead of an array; guards.web.adapter: [] left empty.","commonSituations":"Hand-written auth config arrays missing nested sections; YAML/PHP config merge that silently drops the adapter block; environment-specific config overriding adapter with a scalar; refactoring that emptied the array during a rename.","solutions":["Add the missing non-empty array under the key named in the message - most commonly: guards: {web: {adapter: {name: 'stream', options: {...}}, type: 'session'}}","If the value was a scalar/null, convert it to the array shape the component documents","Validate your auth config at boot (schema/assertion) so mistakes surface with your own error before the factory runs"],"exampleFix":"// before\n'guards' => [\n    'web' => ['type' => 'session'],\n],\n\n// after\n'guards' => [\n    'web' => [\n        'adapter' => ['name' => 'stream', 'options' => ['file' => 'storage/users.json']],\n        'type' => 'session',\n    ],\n],","handlingStrategy":"validation","validationCode":"foreach ($config['guards'] ?? [] as $name => $guard) {\n    if (!isset($guard['adapter']) || !is_array($guard['adapter']) || $guard['adapter'] === []) {\n        throw new InvalidArgumentException(\"guard '{$name}' needs a non-empty 'adapter' array\");\n    }\n}","typeGuard":"function hasNonEmptyArrayOption(array $options, string $key): bool\n{\n    return isset($options[$key]) && is_array($options[$key]) && $options[$key] !== [];\n}","tryCatchPattern":null,"preventionTips":["Validate the auth config shape once at boot instead of relying on factory-time errors","Use a typed config object/schema for auth configuration so missing blocks cannot pass silently","Beware config merges: assert the merged result, not each fragment"],"tags":["auth","options","configuration","validation"],"backgroundTag":"missing-required-config-key","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}