{"record":{"id":"7a16e1eeedd43572","repo":"phalcon/cphalcon","slug":"stream-adapter-file-is-not-valid-json-path","errorCode":null,"errorMessage":"Stream adapter file is not valid JSON: {path}","messagePattern":"Stream adapter file is not valid JSON: (.+?)","errorType":"exception","errorClass":"Phalcon\\Auth\\Exceptions\\FileNotValidJson","httpStatus":null,"severity":"error","filePath":"phalcon/Auth/Adapter/Stream.zep","lineNumber":85,"sourceCode":"    {\n        var contents, data, ex, path, rows;\n\n        let path = this->config->getFile();\n\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":67,"sourceCodeEnd":98,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Auth/Adapter/Stream.zep#L67-L98","documentation":"The Auth Stream adapter decodes its users file with Phalcon's Json Decode helper; if that throws InvalidArgumentException the adapter wraps it in FileNotValidJson (chaining the original exception) with the file path. The file exists and is readable, but its contents are not syntactically valid JSON.","triggerScenarios":"First authentication attempt against a users file containing JSON syntax errors: comments, trailing commas, single-quoted strings, unquoted keys, a BOM, or hand-editing mistakes. Decoding is associative (second arg true), but the failure here is parse-level, not shape-level.","commonSituations":"Manually editing the users file to add a user and breaking syntax; generators emitting JSON5-style output; files saved with a UTF-8 BOM by editors; an empty file is valid only if it contains a valid value — a totally empty string fails.","solutions":["Validate and locate the error: `php -r 'json_decode(file_get_contents($path), true); echo json_last_error_msg();'`","Fix the JSON: double quotes, no comments/trailing commas, no BOM; wrap strings in quotes","Seed empty stores with a literal `[]` rather than an empty file","Use `jsonlint` or editor JSON validation before committing changes to the file"],"exampleFix":"// before (storage/users.json)\n{\n    // administrators\n    'admin': { 'password': '...', },\n}\n// after\n[\n    {\"username\": \"admin\", \"password\": \"$2y$10$...\"}\n]","handlingStrategy":"validation","validationCode":"$raw = file_get_contents($config->getFile());\njson_decode((string) $raw, true);\nif (json_last_error() !== JSON_ERROR_NONE) {\n    throw new RuntimeException('Users file is not valid JSON: ' . json_last_error_msg());\n}\n$adapter = new \\Phalcon\\Auth\\Adapter\\Stream($hasher, $config);","typeGuard":null,"tryCatchPattern":"try {\n    $guard->attempt($credentials);\n} catch (\\Phalcon\\Auth\\Exceptions\\FileNotValidJson $e) {\n    $logger->critical('Auth users file failed JSON validation: ' . $e->getMessage());\n    $previous = $e->getPrevious(); // original decode exception with offset details\n    throw new RuntimeException('Authentication store corrupt', 0, $e);\n}","preventionTips":["Validate users.json with jsonlint or `json_last_error()` in CI before deploy","Generate/modify the file programmatically (json_encode) instead of hand-editing","Keep files ASCII/UTF-8 without BOM; seed empty stores with a literal []"],"tags":["auth","stream-adapter","json","configuration"],"backgroundTag":"json-parse-error","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}