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
- Insert FlexObject instances only: fetch/create the object first, then $collection->set($key, $object).
- 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.
- 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
- Treat FlexIndex as an index of FlexObject instances only — hydrate raw rows before set().
- Null-guard chained lookups before inserting their results.
- Use ArrayCollection when you must store arbitrary values.
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
- Invalid argument $element
- Flex Directory not defined, object is not fully defined
- Cache key must be string, "%s" given
- Expiration date must be an integer, a DateInterval or null,
- __METHOD__(): You need to pass option 'directory'
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/6e7248871f3416d9.
Report an issue: GitHub.