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
- Remove the addFramework() call and register the framework's CSS/JS explicitly through Grav's Assets API, for example $grav['assets']->addJs(...) and addCss(...).
- Strip the frameworks entry from serialized HtmlBlock data before render.
- If this is required functionality, implement registerFrameworks() in a fork or patch and upstream the change; the current shipped implementation intentionally rejects it.
- 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
- Do not call HtmlBlock::addFramework() before Grav's render integration.
- Register framework files with the Assets manager directly.
- Reject serialized blocks containing frameworks until supported.
- Add render tests for every custom HtmlBlock producer.
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
- {% link with x %}: x is not an array
- {% link in x %}: x is not a string
- {% script with x %}: x is not an array
- {% script in x %}: x is not a string
- {% {$this->tagName} with x %}: x is not an array
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/76e1c9b6794d12e2.
Report an issue: GitHub.