getgrav/grav · error · InvalidArgumentException

Invalid argument $value

Error message

Invalid argument $value

What it means

AbstractIndexCollection (base of FlexIndex) stores lightweight element metadata, not the elements themselves; set() therefore requires $value to pass isAllowedElement(). In Flex collections that check is `$value instanceof FlexObject`, so calling set() with anything else (array, scalar, stdClass, other object) throws InvalidArgumentException('Invalid argument $value').

Source

Thrown at system/src/Grav/Framework/Collection/AbstractIndexCollection.php:284

        return array_values($this->loadElements($this->entries));
    }

    /**
     * {@inheritDoc}
     */
    #[\ReturnTypeWillChange]
    public function count()
    {
        return count($this->entries);
    }

    /**
     * {@inheritDoc}
     */
    public function set($key, $value)
    {
        if (!$this->isAllowedElement($value)) {
            throw new InvalidArgumentException('Invalid argument $value');
        }

        $this->entries[$key] = $this->getElementMeta($value);
    }

    /**
     * {@inheritDoc}
     */
    public function add($element)
    {
        if (!$this->isAllowedElement($element)) {
            throw new InvalidArgumentException('Invalid argument $element');
        }

        $this->entries[$this->getCurrentKey($element)] = $this->getElementMeta($element);

        return true;
    }

View on GitHub (pinned to 6040efed04)

Solutions

  1. Insert FlexObject instances only: fetch/create the object first, then $collection->set($key, $object).
  2. If you hold raw data, instantiate the object via the Flex type (e.g. $flexCollection->getObject() pathways or the object's create/update API) before adding.
  3. For arbitrary key=>value storage, use ArrayCollection/ArrayObject instead of an index collection.

Example fix

// before
$index->set('abc123', ['title' => 'Hello']); // array -> InvalidArgumentException

// after
$object = $flex->createObject(['title' => 'Hello'], 'abc123');
$index->set('abc123', $object); // FlexObject passes isAllowedElement()
Defensive patterns

Strategy: type-guard

Type guard

use Grav\Framework\Flex\FlexObject;

function isFlexElement(mixed $value): bool
{
    return $value instanceof FlexObject;
}

if (isFlexElement($value)) {
    $index->set($key, $value);
} else {
    // hydrate first or use ArrayCollection for raw data
}

Prevention

When it happens

Trigger: Calling $flexIndex->set($key, ['field' => 'value']) with a raw data array instead of a FlexObject; inserting a plain entity/DTO object from another ORM; reusing code written against ArrayCollection (which accepts anything) against a FlexIndex; set() with the result of a failed lookup (null).

Common situations: Custom Flex object types where developers try to seed the index with unhydrated rows; migrating array-based page collection code to Flex collections; plugins that manipulate Flex collections generically without checking the element contract.

Related errors


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/6e7248871f3416d9. Report an issue: GitHub.