flarum/framework · error · BadRequestException
fields must be an array
Error message
fields must be an array
What it means
RequestUtil::extractFields() reads the 'fields' query parameter used for sparse fieldset filtering. If the client sends ?fields= as a non-array value (a plain string instead of field => array pairs), the method rejects it with BadRequestException because per-field selections must be structured as arrays.
Solutions
- Change the client to send fields as sub-arrays: ?fields[users]=name,email
- Wrap the call in try-catch and return a 400 response guiding the client to the correct format
- Pre-normalize the query param in middleware so a string 'fields' is converted or rejected before reaching extractFields
Example fix
// before GET /api/posts?fields=title,body // after GET /api/posts?fields[posts]=title,body
Defensive patterns
Strategy: type-guard
Validate before calling
$fields = $request->getQueryParams()['fields'] ?? null;
if ($fields !== null && ! is_array($fields)) {
throw new BadRequestException('fields must be an array of field => value pairs');
} Type guard
function isStringKeyedArray($v): bool { return is_array($v) && (array_is_list($v) ? $v === [] : true) && $v === [] || (is_array($v) && ! array_is_list($v)); } Try / catch
try {
$fields = RequestUtil::extractFields($request, $available);
} catch (BadRequestException $e) {
return response()->json(['error' => 'fields must be sent as ?fields[type]=a,b'], 400);
} Prevention
- Always send sparse fieldsets as ?fields[type]=a,b with array bracket syntax
- Document the expected fields format in your API client library
- Add integration tests asserting 400 responses for malformed fields params
When it happens
Trigger: Calling extractFields() on a request whose query string is e.g. ?fields=name,email (bare string) instead of ?fields[users]=name,email; any GET where 'fields' resolves to a scalar via $request->getQueryParams().
Common situations: API clients hand-building query strings without PHP array bracket syntax; copying examples that flatten fields into a comma list; proxies or gateways dropping the square brackets from fields[...] parameters.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- Invalid fields [
- flarum-akismet.admin.akismet_settings.invalid_api_key_messag…
- Incorrect password
- Invalid erasure mode: $mode
- You can only use page[near] with filter[dialog] and the…
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/beaf1fc12852092d.
Report an issue: GitHub.
Appendix: source
Thrown at framework/core/src/Http/RequestUtil.php:238
}
public static function extractFilter(Request $request): array
{
$filter = $request->getQueryParams()['filter'] ?? [];
if (! is_array($filter)) {
throw new BadRequestException('filter must be an array');
}
return $filter;
}
public static function extractFields(Request $request, ?array $available = null): array
{
$fields = $request->getQueryParams()['fields'] ?? [];
if (! is_array($fields)) {
throw new BadRequestException('fields must be an array');
}
if ($available !== null) {
$invalid = array_diff(array_keys($fields), $available);
if (count($invalid)) {
throw new BadRequestException('Invalid fields ['.implode(',', $invalid).']');
}
}
return $fields;
}
}
View on GitHub (pinned to 4b939f6853)