Codeinwp / Codeinwp/otter-blocks

Frontend CSS generation crashes when Core_Image_Plugin_CSS is absent from Composer classmap

Open
#2,970 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug-report bug-report-triage crash-report
Dominant language
JavaScript
Stars
198
Forks
36
Avg merge
3d 4h
Merged PRs (30d)
30

Description

Summary

Otter frontend CSS generation can terminate with Class ".../Core_Image_Plugin_CSS" not found.

Expected behavior: CSS generation completes or safely avoids an unavailable bundled CSS handler.

Actual behavior: Rendering reaches an uncaught exception while generating widget CSS, producing a frontend failure.

Impact: The affected site recorded repeated frontend crashes, including on its 404 template path.

Customer context

  • Product / area: Otter Blocks frontend widget CSS generation
  • Version: 3.2.1
  • Environment: WordPress 7.0.3; PHP 8.3.33
  • Integration / third party: Composer autoloading; Themeisle SDK 3.3.59 is present but telemetry identifies the crash as outside SDK code.
  • Reported error / symptom: Class ".../Core_Image_Plugin_CSS" not found at inc/class-base-css.php:343
  • Impact: 1,150 telemetry occurrences across one site between 2026-08-08 and 2026-08-09.

Reproduction notes

  1. Use Otter Blocks 3.2.1 with a Composer classmap that does not resolve the bundled Core_Image_Plugin_CSS class while its PHP file remains present.
  2. Trigger frontend widget CSS generation.
  3. The reported production path reaches an uncaught class-not-found exception at Base_CSS::cycle_through_static_blocks().

Production reproduction is confirmed by telemetry; the classmap mismatch has not been recreated locally.

Diagnosis

Conclusion

Telemetry provides a direct production stack trace to Otter's CSS-generation loop. In 3.2.1, the loop unconditionally instantiates every registered CSS handler, including Core_Image_Plugin_CSS. The class file is present, but Otter loads its own inc/ classes only through Composer's generated classmap. This establishes a confirmed crash path when that generated map does not resolve a bundled class.

Where this likely occurs
  • inc/class-base-css.phpBase_CSS::autoload_block_classes() lines 72-105 registers ThemeIsle\GutenbergBlocks\CSS\Blocks\Core_Image_Plugin_CSS at line 82.
  • inc/class-base-css.phpBase_CSS::cycle_through_static_blocks() lines 338-368 dynamically instantiates each registered handler at line 343 before testing whether it matches the parsed block.
  • inc/css/blocks/class-core-image-plugin-css.phpCore_Image_Plugin_CSS lines 8-17 defines the referenced bundled class and lines 24-31 identifies it with core/image.
  • composer.jsonautoload lines 61-65 exposes inc/ exclusively as a Composer classmap.
  • Commit fb75ec381f6cb6d74ebb96a8afe2baa1f6a09fbd on origin/fix/2954-autoload-missing-class documents the same stale-classmap failure mode and is not present in the inspected 3.2.1 checkout.
Engineering notes

The production stack reaches Base_CSS::get_widgets_css() and the same class cycle is also used for post and reusable-block CSS. Because instantiation occurs before the block-name comparison, the missing class can terminate generation even where the parsed block does not map to core/image.

The failure is conditional on an inconsistent or stale Composer autoload artifact. The available source confirms the class file and the unguarded dynamic instantiation; it does not identify why the affected installation's classmap was stale. WordPress core behavior was not inspected.

Test coverage status

No relevant coverage was found during inspection of the 3.2.1 test suite: searches found no test referencing cycle_through_static_blocks or Core_Image_Plugin_CSS. The later branch for commit fb75ec38 includes tests/test-main-autoload.php coverage for resolving plugin class names, but that coverage is absent from the inspected release and does not directly exercise this CSS loop.

What to verify or explore next
  • May be worth reproducing on an Otter 3.2.1 installation where the Composer classmap omits inc/css/blocks/class-core-image-plugin-css.php.
  • If reproducible, checking widget, post, and reusable-block CSS-generation routes would establish the affected surface.
  • Comparing the distributed 3.2.1 archive's vendor/composer metadata with the source class list may clarify whether packaging or interrupted updates produce the mismatch.
Unknowns / follow-up
  • The telemetry does not include the affected installation's generated Composer classmap or update history.
  • The available evidence does not establish the frequency of stale classmaps outside the reported site.

Confidence

Confidence: 96/100

Production telemetry records 1,150 frontend uncaught exceptions in Otter 3.2.1, and the reported line dynamically instantiates a registered class without an availability check. The class source exists, while the released code relies solely on Composer's generated classmap; an unreleased Otter commit explicitly documents stale classmaps as making shipped classes unloadable.

Crash telemetry

Occurrences 1150
Distinct sites 1
First seen 2026-08-08 06:19 UTC
Last seen 2026-08-09 04:45 UTC
Crash location product:inc/class-base-css.php:343
Request context frontend
Inside Themeisle SDK no
Product versions 3.2.1
WP versions 7.0.3
PHP versions 8.3.33
SDK versions 3.3.59

Source: automated crash report — otter-blocks, fingerprint 96c2c65815a8d2c2808444e3c21fbf69
Generated by bug-report-triage (ID: bug-report-triage_6a78177e3bbad4.91799189)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with inc/class-base-css.php, especially Base_CSS::autoload_block_classes() and cycle_through_static_blocks(), then inspect inc/css/blocks/class-core-image-plugin-css.php and the Composer classmap configuration in composer.json. Check the widget, post, and reusable-block CSS-generation paths and existing tests; done means unavailable bundled handlers no longer cause uncaught frontend failures and the behavior is covered by tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
php, wordpress
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
67/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.