{"record":{"id":"0a351f94967b7fc3","repo":"phalcon/cphalcon","slug":"auth-context-requires-key-to-be-a-non-empty-0a351f","errorCode":null,"errorMessage":"Auth {context} requires '{key}' to be a non-empty string","messagePattern":"Auth (.+?) requires '(.+?)' to be a non-empty string","errorType":"exception","errorClass":"Phalcon\\Auth\\Exceptions\\OptionRequiresString","httpStatus":null,"severity":"error","filePath":"phalcon/Auth/Internal/Options.zep","lineNumber":77,"sourceCode":"            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);\n        }\n\n        return value;\n    }\n\n    /**\n     * @param array<string, mixed> $options\n     */\n    public static function stringOrNull(array options, string key) -> string | null\n    {\n        var value;\n\n        fetch value, options[key];\n\n        return typeof value === \"string\" ? value : null;\n    }\n}\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Auth/Internal/Options.zep#L59-L95","documentation":"Options::requireString() validates string-valued config entries for the Auth component. It throws OptionRequiresString (message includes the failing context and key) when the key is missing from the options array, the value is not a string (int, array, null...), or it is the empty string ''. Common call sites are ManagerFactory requiring each guard's 'type', buildAdapter requiring the adapter 'name', and the Stream adapter requiring 'file'.","triggerScenarios":"Auth config entries like guards.web.type missing or set to null; guards.web.adapter.name: 123 (int) or '' (empty); a Stream adapter built with fromOptions() where the 'file' key is absent; adapter name defined with leading/trailing whitespace only.","commonSituations":"Env-driven config where an env var resolves to empty string in some environment; config merge that drops scalar keys; copy-paste of a guard block that kept the adapter name but lost 'type'; YAML parsing a numeric-looking name as int.","solutions":["Set the named key to a non-empty string - match the exact key in the message ('type', 'name', or 'file')","Cast or normalize values from env/YAML: (string) guards.web.type, and default empty strings to real values","Add a boot-time check that required config keys are non-empty strings before handing config to ManagerFactory::load()"],"exampleFix":"// before\n'guards' => [\n    'web' => [\n        'adapter' => ['name' => '', 'options' => []],\n        'type' => null,\n    ],\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    foreach (['type'] as $key) {\n        $v = $guard[$key] ?? null;\n        if (!is_string($v) || $v === '') {\n            throw new InvalidArgumentException(\"guard '{$name}' needs a non-empty string '{$key}'\");\n        }\n    }\n}","typeGuard":"function hasNonEmptyStringOption(array $options, string $key): bool\n{\n    return isset($options[$key]) && is_string($options[$key]) && $options[$key] !== '';\n}","tryCatchPattern":null,"preventionTips":["Default env-derived strings at load time (?: fallback) so empty strings never reach the factory","Cast YAML/env scalars to string explicitly when building config arrays","Run a config lint step that rejects empty or non-string required keys"],"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"}