{"record":{"id":"1ea9cadf1b29d9d9","repo":"phalcon/cphalcon","slug":"stream-adapter-file-does-not-contain-a-json-array","errorCode":null,"errorMessage":"Stream adapter file does not contain a JSON array: {path}","messagePattern":"Stream adapter file does not contain a JSON array: (.+?)","errorType":"exception","errorClass":"Phalcon\\Auth\\Exceptions\\FileDoesNotContainJson","httpStatus":null,"severity":"error","filePath":"phalcon/Auth/Adapter/Stream.zep","lineNumber":89,"sourceCode":"\n        if (!this->phpFileExists(path)) {\n            throw new FileDoesNotExist(path);\n        }\n\n        let contents = this->phpFileGetContents(path);\n\n        if (contents === false) {\n            throw new FileCannotRead(path);\n        }\n\n        try {\n            let data = (new Decode())->__invoke(contents, true);\n        } catch InvalidArgumentException, ex {\n            throw new FileNotValidJson(path, ex);\n        }\n\n        if (typeof data !== \"array\") {\n            throw new FileDoesNotContainJson(path);\n        }\n\n        /** @var list<AuthUserRow> $rows */\n        let rows = array_values(data);\n\n        return rows;\n    }\n}\n","sourceCodeStart":71,"sourceCodeEnd":98,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Auth/Adapter/Stream.zep#L71-L98","documentation":"The Stream auth adapter (Phalcon\\Auth\\Adapter\\Stream) loads its users from a JSON file that must be a top-level JSON array of user records, e.g. [{\"id\":1,...},{...}]. This error means the file was read and decoded successfully, but the decoded top-level value is not an array - typically a JSON object like {\"users\":[...]} or a scalar/string/number. It is thrown from loadUsers() after the Decode helper succeeded but typeof data !== \"array\".","triggerScenarios":"Any code path that makes the Stream adapter load users: $auth->attempt(...), $auth->validate(...), guard()->user(), or building the adapter via Stream::fromOptions($hasher, ['file' => $path]) and then authenticating - where $path contains valid JSON whose root is an object or scalar instead of an array.","commonSituations":"A users.json authored as {\"users\": [...]} (wrapper object) because that reads more naturally; exporting a single user object {...}; storing a JSON object keyed by user id; hand-editing the file and saving a scalar.","solutions":["Rewrite the users file so the top-level value is a JSON array of user objects: [{\"id\":1,\"email\":\"a@b\",\"password\":\"<hash>\"}, ...]","If you need a wrapper structure, extract the inner list to its own file used by the adapter, or preprocess the file before pointing the adapter at it","Verify the shape before wiring the adapter: $data = json_decode((string) file_get_contents($path), true); assert is_array($data)"],"exampleFix":"// before: storage/users.json\n{\"users\": [{\"id\":1,\"email\":\"a@b\",\"password\":\"...\"}]}\n\n// after: storage/users.json\n[{\"id\":1,\"email\":\"a@b\",\"password\":\"...\"}]","handlingStrategy":"validation","validationCode":"$path = 'storage/users.json';\n$data = json_decode((string) file_get_contents($path), true);\nif (!is_array($data)) {\n    throw new InvalidArgumentException(\"{$path} must contain a top-level JSON array of users\");\n}","typeGuard":"function isTopLevelJsonArray(string $json): bool\n{\n    return is_array(json_decode($json, true));\n}","tryCatchPattern":"try {\n    $auth->guard('web')->attempt($credentials);\n} catch (\\Phalcon\\Auth\\Exceptions\\FileDoesNotContainJson $e) {\n    // report the file path from the message; treat as configuration error, do not retry\n}","preventionTips":["Keep users fixtures as top-level arrays and assert the shape in a build/CI step","Add a smoke check at boot: json_decode the file and is_array it before wiring the Stream adapter","If multiple shapes exist in your project, write the users file via a generator you control rather than by hand"],"tags":["auth","json","stream-adapter","configuration"],"backgroundTag":"invalid-json-format","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}