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

  1. Change the client to send fields as sub-arrays: ?fields[users]=name,email
  2. Wrap the call in try-catch and return a 400 response guiding the client to the correct format
  3. 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

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


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)