laravel/framework · error · InvalidArgumentException

Array value for key [%s] must be an array, %s found.

Error message

Array value for key [%s] must be an array, %s found.

What it means

Thrown by Arr::array() when the value resolved via Arr::get() (with dot notation) is not an array. The accessor exists to give a typed return, so any scalar, object, or null (missing key with no array default) fails.

Source

Thrown at src/Illuminate/Collections/Arr.php:87

    {
        if (is_null(static::get($array, $key))) {
            static::set($array, $key, $value);
        }

        return $array;
    }

    /**
     * Get an array item from an array using "dot" notation.
     *
     * @throws \InvalidArgumentException
     */
    public static function array(ArrayAccess|array $array, string|int|null $key, ?array $default = null): array
    {
        $value = Arr::get($array, $key, $default);

        if (! is_array($value)) {
            throw new InvalidArgumentException(
                sprintf('Array value for key [%s] must be an array, %s found.', $key, gettype($value))
            );
        }

        return $value;
    }

    /**
     * Get a boolean item from an array using "dot" notation.
     *
     * @throws \InvalidArgumentException
     */
    public static function boolean(ArrayAccess|array $array, string|int|null $key, ?bool $default = null): bool
    {
        $value = Arr::get($array, $key, $default);

        if (! is_bool($value)) {
            throw new InvalidArgumentException(

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Pass an array default: Arr::array($config, 'database.options', []).
  2. Validate with Arr::get() + is_array() before calling the typed accessor.
  3. Fix the source data so the key always holds an array.
  4. Use a more specific dot path that lands on the array node.

Example fix

// before
$opts = Arr::array($config, 'database.options');

// after
$opts = Arr::array($config, 'database.options', []);
// or
$v = Arr::get($config, 'database.options');
$opts = is_array($v) ? $v : [];
Defensive patterns

Strategy: type-guard

Validate before calling

$value = Arr::get($config, 'database.options');
if (! is_array($value)) {
    $value = [];
}

Type guard

function arrayKeyIsArray(array $array, string $key): bool {
    return is_array(Arr::get($array, $key));
}

Try / catch

try {
    $opts = Arr::array($config, 'database.options', []);
} catch (\InvalidArgumentException $e) {
    $opts = [];
}

Prevention

When it happens

Trigger: Calling Arr::array($config, 'database.options') when that key holds a scalar string, an object, or is missing and $default is null.

Common situations: Reading a config key whose schema changed; a key that is sometimes a string and sometimes a list; dot path that traverses into a scalar (e.g. 'db.name.extra').

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/7a23830f98eab860.json. Report an issue: GitHub.