{"record":{"id":"04aee8b5e156315d","repo":"flarum/framework","slug":"invalid-fields","errorCode":null,"errorMessage":"Invalid fields [","messagePattern":"Invalid fields \\[","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"framework/core/src/Http/RequestUtil.php","lineNumber":245,"sourceCode":"            throw new BadRequestException('filter must be an array');\n        }\n\n        return $filter;\n    }\n\n    public static function extractFields(Request $request, ?array $available = null): array\n    {\n        $fields = $request->getQueryParams()['fields'] ?? [];\n\n        if (! is_array($fields)) {\n            throw new BadRequestException('fields must be an array');\n        }\n\n        if ($available !== null) {\n            $invalid = array_diff(array_keys($fields), $available);\n\n            if (count($invalid)) {\n                throw new BadRequestException('Invalid fields ['.implode(',', $invalid).']');\n            }\n        }\n\n        return $fields;\n    }\n}\n","sourceCodeStart":227,"sourceCodeEnd":252,"githubUrl":"https://github.com/flarum/framework/blob/4b939f685389bfe8a380e9e28ddf305a1c66950c/framework/core/src/Http/RequestUtil.php#L227-L252","documentation":"When an $available whitelist is passed to RequestUtil::extractFields(), any field key in the 'fields' query param not present in the whitelist triggers BadRequestException listing the invalid keys. This guards against clients requesting sparse fieldsets for relationship types the endpoint does not expose.","triggerScenarios":"GET with e.g. ?fields[user]=name on an endpoint that only allows $available=['posts']; any typo in the fields sub-key; requesting fields for a relationship removed in a newer API version.","commonSituations":"Client-server API version skew after renames; typos in relationship names; copy-pasted query strings between endpoints with different whitelists.","solutions":["Change the query to use only whitelisted keys shown in the error message","Fix the typo or update the client to the current relationship name","On the server, extend the $available array if the field is legitimately supported","Catch BadRequestException and return it to the client with the list of allowed fields"],"exampleFix":"// before\nGET /api/posts?fields[usr]=title\n// after\nGET /api/posts?fields[posts]=title","handlingStrategy":"validation","validationCode":"$requested = array_keys((array) ($request->getQueryParams()['fields'] ?? []));\n$allowed = ['posts', 'users'];\nif (count(array_diff($requested, $allowed))) { /* reject before calling */ }","typeGuard":null,"tryCatchPattern":"try {\n    $fields = RequestUtil::extractFields($request, ['posts', 'users']);\n} catch (BadRequestException $e) {\n    return response()->json(['error' => $e->getMessage(), 'allowed' => ['posts','users']], 400);\n}","preventionTips":["Keep the client's field keys in sync with the server whitelist per endpoint","Version your API and update clients when whitelists change","Return the allowed field list in error responses or API docs"],"tags":["http","query-parameters","bad-request","validation"],"backgroundTag":"invalid-query-parameter","analyzedSha":"4b939f685389bfe8a380e9e28ddf305a1c66950c","analyzedAt":"2026-09-15T18:09:20.879Z","contentChangedAt":"2026-09-15T18:09:20.879Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}