getgrav/grav · error · RuntimeException

Not Implemented

Error message

Not Implemented

What it means

BlockAssets::registerFrameworks() is an explicit stub: any non-empty frameworks asset list immediately throws RuntimeException. When Grav renders an HtmlBlock outside a parent ContentBlock, TwigNodeRender compiles a call to BlockAssets::registerAssets(), which dispatches the frameworks category to this unimplemented method.

Source

Thrown at system/src/Grav/Common/Assets/BlockAssets.php:64

                case 'links':
                    static::registerLinks($assets, $groups);
                    break;
                case 'html':
                    static::registerHtml($assets, $groups);
                    break;
            }
        }
    }

    /**
     * @param Assets $assets
     * @param array $list
     * @return void
     */
    protected static function registerFrameworks(Assets $assets, array $list): void
    {
        if ($list) {
            throw new \RuntimeException('Not Implemented');
        }
    }

    /**
     * @param Assets $assets
     * @param array $groups
     * @return void
     */
    protected static function registerStyles(Assets $assets, array $groups): void
    {
        $grav = Grav::instance();

        /** @var Config $config */
        $config = $grav['config'];

        foreach ($groups as $group => $styles) {
            foreach ($styles as $style) {
                switch ($style[':type']) {

View on GitHub (pinned to 6040efed04)

Solutions

  1. Remove the addFramework() call and register the framework's CSS/JS explicitly through Grav's Assets API, for example $grav['assets']->addJs(...) and addCss(...).
  2. Strip the frameworks entry from serialized HtmlBlock data before render.
  3. If this is required functionality, implement registerFrameworks() in a fork or patch and upstream the change; the current shipped implementation intentionally rejects it.
  4. Catch unsupported block shapes during development and fail with a clear plugin-level message instead of rendering them.

Example fix

// before
$block = HtmlBlock::create('widget');
$block->addFramework('jquery');
$html = $block->render(); // render path calls BlockAssets::registerAssets()

// after
$block = HtmlBlock::create('widget');
$grav['assets']->addJs('plugin://my-plugin/assets/jquery.min.js');
$html = $block->render();
Defensive patterns

Strategy: validation

Validate before calling

$assets = $block->getAssets();
if (!empty($assets['frameworks'])) {
    throw new InvalidArgumentException('HtmlBlock frameworks are not supported by BlockAssets::registerAssets().');
}
$html = $block->render();

Type guard

function hasRenderableBlockAssets(HtmlBlock $block): bool
{
    $assets = $block->getAssets();
    return empty($assets['frameworks']);
}

Try / catch

try {
    BlockAssets::registerAssets($block);
} catch (RuntimeException $e) {
    if ($e->getMessage() === 'Not Implemented') {
        throw new LogicException('Register framework CSS/JS directly; frameworks are unsupported.', 0, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Create an HtmlBlock, call $block->addFramework('jquery') or build it from serialized data containing a frameworks array, then render it through Grav's {% render %} node so registerAssets() runs. The non-empty list reaches BlockAssets.php:63-65 and throws 'Not Implemented'.

Common situations: A plugin or custom render implementation uses HtmlBlock::addFramework() expecting Grav to enqueue jQuery or another framework, or cached/serialized block data from older code contains frameworks entries and is rendered after an upgrade.

Related errors


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