getgrav/grav · error · RuntimeException

Flex Directory not defined, object is not fully defined

Error message

Flex Directory not defined, object is not fully defined

What it means

FlexIndex is a lazy collection that needs a FlexDirectory to resolve its entries; if the private _flexDirectory was never set, getFlexDirectory() throws 'Flex Directory not defined, object is not fully defined'. Indexes are meant to be built through a directory (getIndex()) or via createFromStorage/createFromEntries with a directory option, so hitting this means the index was constructed incompletely.

Source

Thrown at system/src/Grav/Framework/Flex/FlexIndex.php:202

    }

    /**
     * {@inheritdoc}
     * @see FlexCollectionInterface::getFlexType()
     */
    public function getFlexType(): string
    {
        return $this->getFlexDirectory()->getFlexType();
    }

    /**
     * {@inheritdoc}
     * @see FlexCollectionInterface::getFlexDirectory()
     */
    public function getFlexDirectory(): FlexDirectory
    {
        if (null === $this->_flexDirectory) {
            throw new RuntimeException('Flex Directory not defined, object is not fully defined');
        }

        return $this->_flexDirectory;
    }

    /**
     * {@inheritdoc}
     * @see FlexCollectionInterface::getTimestamp()
     */
    public function getTimestamp(): int
    {
        $timestamps = $this->getTimestamps();

        return $timestamps ? max($timestamps) : time();
    }

    /**
     * {@inheritdoc}

View on GitHub (pinned to 6040efed04)

Solutions

  1. Build indexes from the directory: $index = $flex->getDirectory('pages')->getIndex();.
  2. When using static creators, always pass the directory: FlexIndex::createFromEntries($entries, ['directory' => $directory]).
  3. Cache only plain entry arrays and rebuild the index after retrieval.
  4. If you subclass FlexIndex, ensure the constructor/create path sets the directory.

Example fix

// before
$index = FlexIndex::createFromArray(['entries' => $entries]);
$type = $index->getFlexType(); // throws

// after
$index = FlexIndex::createFromEntries($entries, ['directory' => $directory]);
$type = $index->getFlexType();
Defensive patterns

Strategy: validation

Validate before calling

// Only use directory-derived indexes; when building manually, always pass the directory
$directory = $grav['flex']->getDirectory($type);
$index = $directory->getIndex(); // safe: directory guaranteed
// manual path:
$index = FlexIndex::createFromEntries($entries, ['directory' => $directory]);

Try / catch

try {
    $directory = $index->getFlexDirectory();
} catch (\Grav\Framework\Flex\Exception\RuntimeException $e) {
    // index was built incompletely: rebuild from the flex registry
    $directory = $grav['flex']->getDirectory($fallbackType);
    $index->setFlexDirectory($directory);
}

Prevention

When it happens

Trigger: Calling getFlexType()/getFlexDirectory()/render() or any directory-dependent method on an index built with FlexIndex::createFromArray(['entries' => [...]]) without passing 'directory' in options; unserializing a cached index whose directory link was lost; subclass code that forgot to call setFlexDirectory().

Common situations: Custom collections assembled by hand in plugins instead of via $directory->getIndex(); caching FlexIndex objects directly in a cache backend; upgrading Grav versions where index internals changed shape.

Related errors


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