Codeinwp / Codeinwp/otter-blocks
Frontend CSS traversal exhausts memory through repeated Base_CSS init registrations
- Dominant language
- JavaScript
- Stars
- 198
- Forks
- 36
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 30
Description
Summary
Frontend rendering can terminate with Allowed memory size of 134217728 bytes exhausted while Otter Blocks generates CSS for block content.
Expected behavior: CSS generation completes within the configured PHP memory limit for supported page content.
Actual behavior: dynamic CSS traversal can accumulate enough memory to trigger a fatal error.
Impact: the affected frontend request returns a fatal error instead of rendering the page.
Customer context
- Product / area: Otter Blocks frontend dynamic CSS generation
- Version: 3.2.1
- Environment: WordPress 7.0.2, PHP 8.1.34, 128 MB memory limit
- Integration / third party: None identified; telemetry marks the location as outside the Themeisle SDK
- Reported error / symptom:
Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)atinc/class-base-css.php:63 - Impact: 2 captured occurrences across 1 site in the query window
Reproduction notes
- Use Otter Blocks 3.2.1 with a frontend request that reaches dynamic or inline CSS generation for content containing many supported blocks; nested blocks increase the traversed count.
- Configure PHP with a 128 MB memory limit.
- The reported production request fatals with
Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)atinc/class-base-css.php:63.
Reproduction was not run locally because the telemetry report does not provide the affected content or complete call stack.
Diagnosis
Conclusion
Production telemetry records a frontend memory-exhaustion fatal at Base_CSS::__construct() line 63. In the released code, Base_CSS::cycle_through_static_blocks() creates every configured CSS renderer for every parsed block. Each renderer inherits the constructor, which registers an init callback bound to that newly created object. This creates request-scoped hook registrations and object retention proportional to the number of blocks times registered renderers. The reported allocation at the registration call is consistent with this path.
Where this likely occurs
inc/class-base-css.php—Base_CSS::__construct()lines 62-64 registersautoload_block_classesoninitfor each instance; this is the exact telemetry location and unchanged at release tagv3.2.1.inc/class-base-css.php—Base_CSS::cycle_through_static_blocks()lines 338-360 loops through parsed blocks andself::$blocks_classes, creating each renderer at line 343 before selecting the matching renderer.inc/css/class-block-frontend.php—Block_Frontend::cycle_through_blocks()lines 498-503 invokes the static-block traversal during inline frontend CSS generation;Block_Frontend::get_page_css_inline()lines 461-485 parses page content and reaches that method.inc/css/class-block-frontend.php—Block_Frontend::enqueue_styles()lines 262-298 can schedule CSS generation or inline output when a post has blocks and no CSS file is available.inc/class-base-css.php—Base_CSS::autoload_block_classes()lines 72-105 defines the renderer list traversed for each parsed block.
Engineering notes
The matching renderer is not selected before instantiation: the traversal constructs all registered renderer classes, then checks each class's block prefix. Because those classes extend Base_CSS, the inherited constructor invokes add_action() for every constructed renderer. Nested blocks recurse through the same traversal at lines 358-360, increasing registrations with content depth and block count. The production report has no structured stack trace, so the exact page content and renderer count are unknown. The implicated source is Otter Blocks, not the bundled Themeisle SDK.
Test coverage status
tests/test-css.php covers CSS_Utility output only. The inspected suite tests/test-atomic-wind-blocks.php covers Atomic Wind frontend CSS behavior but not Base_CSS::cycle_through_static_blocks() registration growth. No relevant coverage was found during inspection for repeated renderer construction, init callback counts, or bounded memory during normal block CSS traversal.
What to verify or explore next
- May be worth reproducing a frontend request with a high number of supported and nested blocks under a 128 MB PHP memory limit, with no generated CSS file available.
- May be worth observing the number of
initcallbacks and retained renderer objects before and afterBase_CSS::cycle_through_static_blocks()for multi-block content. - If reproducible, checking inline, preview, widget, reusable-block, and CSS-file generation paths would establish the affected surface.
Unknowns / follow-up
- The telemetry report does not include the post content, active blocks, generated CSS size, or a structured stack trace.
- The observed two occurrences establish a production failure but do not establish affected-site prevalence.
Confidence
Confidence: 91/100
Production telemetry captured two frontend fatal errors on one site in Otter Blocks 3.2.1 at an allocation site that the inspected CSS traversal reaches once per renderer instance. The released code repeatedly creates renderer objects whose inherited constructor registers each instance on init, providing strong code-level evidence of request-scoped memory growth rather than an SDK failure.
Crash telemetry
| Occurrences | 2 |
| Distinct sites | 1 |
| First seen | 2026-08-03 16:22 UTC |
| Last seen | 2026-08-03 16:22 UTC |
| Crash location | product:inc/class-base-css.php:63 |
| Request context | frontend |
| Inside Themeisle SDK | no |
| Product versions | 3.2.1 |
| WP versions | 7.0.2 |
| PHP versions | 8.1.34 |
| SDK versions | 3.3.59 |
Source: automated crash report — otter-blocks, fingerprint 3d80ae1906bf4a71d0cbe6e0de4c80d8
Generated by bug-report-triage (ID: bug-report-triage_6a717ffb943590.36844717)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.