getgrav/grav · error · RuntimeException

Grav\Framework\Flex\Pages\Traits\PageLegacyTrait::file(): No

Error message

Grav\Framework\Flex\Pages\Traits\PageLegacyTrait::file(): Not Implemented

What it means

The legacy Page API exposes file() to get the MarkdownFile instance behind a page, but Flex pages are not backed by a single file object exposed this way, so PageLegacyTrait::file() always throws 'Not Implemented'. Flex page storage may be multi-file, database-backed, or formatted differently, so the one-file abstraction does not hold.

Source

Thrown at system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php:261

            'content' => $this->_content,
            'content_meta' => $this->_content_meta
        ];

        $cache = $this->getCache('render');
        $key = md5($this->getCacheKey() . '-content');

        $cache->set($key, $value);
    }

    /**
     * Get file object to the page.
     *
     * @return MarkdownFile|null
     */
    public function file(): ?MarkdownFile
    {
        // TODO:
        throw new RuntimeException(__METHOD__ . '(): Not Implemented');
    }

    /**
     * Prepare move page to new location. Moves also everything that's under the current page.
     *
     * You need to call $this->save() in order to perform the move.
     *
     * @param PageInterface $parent New parent page.
     * @return $this
     */
    public function move(PageInterface $parent)
    {
        if ($this->route() === $parent->route()) {
            throw new RuntimeException('Failed: Cannot set page parent to self');
        }
        $rawRoute = $this->rawRoute();
        if ($rawRoute && Utils::startsWith($parent->rawRoute(), $rawRoute)) {
            throw new RuntimeException('Failed: Cannot set page parent to a child of current page');

View on GitHub (pinned to 6040efed04)

Solutions

  1. Use the storage layer instead: $page->getFlexDirectory()->getStorage()->readRaw($page->getStorageKey()) when raw access is needed.
  2. Use property access ($page->markdown(), $page->raw()) for content rather than the file object.
  3. Branch on instanceof FlexPageObject before calling file() in shared code paths.

Example fix

// before
$markdownFile = $page->file(); // throws for Flex pages

// after
$raw = $page->getFlexDirectory()->getStorage()->readRaw($page->getStorageKey());
Defensive patterns

Strategy: fallback

Validate before calling

// Route raw-file access away from the legacy API on Flex pages
if ($page instanceof \Grav\Framework\Flex\Pages\FlexPageObject) {
    $raw = $page->getFlexDirectory()->getStorage()->readRaw($page->getStorageKey());
} else {
    $file = $page->file();
}

Type guard

function isFlexPage(\Grav\Common\Page\Interfaces\PageInterface $page): bool
{
    return $page instanceof \Grav\Framework\Flex\Pages\FlexPageObject;
}

Prevention

When it happens

Trigger: Plugin code calling $page->file()->markdown() or using file() to read/modify the raw markdown of a page obtained from Flex Pages; error handlers or admin themes walking pages and touching ->file().

Common situations: Legacy plugins doing direct file manipulation (mtime checks, markdown rewriting) against PageInterface while the site runs Flex Pages; custom workflows that assume pages == files.

Related errors


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