Summary
Rendering Dynamic Content for an ACF repeater sub-field can terminate the frontend request after PHP reaches its execution-time limit.
Expected behavior: Dynamic Content either resolves the requested repeater sub-field or safely stops when its field hierarchy cannot be traversed.
Actual behavior: The request can run until the configured PHP timeout and produce Maximum execution time of 900 seconds exceeded.
Impact: Affected pages fail to render while the Dynamic Content ACF lookup is evaluated.
Customer context
- Product / area: Otter Pro Dynamic Content, ACF repeater sub-fields
- Version: 3.2.2
- Environment: Frontend requests on WordPress 7.0.4 with PHP 8.1.34 and PHP 8.4.22
- Integration / third party: Advanced Custom Fields
- Reported error / symptom:
Maximum execution time of 900 seconds exceeded
- Impact: 19 production fatal occurrences across 3 distinct sites between 2026-08-13 and 2026-08-15.
Reproduction notes
- Configure an Otter Pro Dynamic Content value that resolves an ACF repeater sub-field whose direct ACF value is empty.
- Provide an ACF field-parent lookup sequence that repeats a previously returned field instead of reaching a missing parent.
- Render the affected content on the frontend.
Reproduction is code-confirmed from the non-terminating traversal; the telemetry does not include the exact ACF configuration needed to recreate the production hierarchy.
Diagnosis
Conclusion
The production location maps exactly to Dynamic_Content::get_acf_repeater_sub_field() at the cursor reassignment inside its while ( true ) parent walk. That loop stops only when acf_get_field() returns no parent and has no repeated-parent or maximum-depth guard. A cyclic ACF field-parent result therefore does not terminate, matching the timeout fatal recorded at line 314.
Where this likely occurs
plugins/otter-pro/inc/plugins/class-dynamic-content.php — Dynamic_Content::evaluate_content() lines 45-64 routes ACF Dynamic Content through get_acf() for frontend rendering when the Pro license hooks are active.
plugins/otter-pro/inc/plugins/class-dynamic-content.php — Dynamic_Content::get_acf() lines 240-257 invokes get_acf_repeater_sub_field() when the selected ACF value is empty.
plugins/otter-pro/inc/plugins/class-dynamic-content.php — Dynamic_Content::get_acf_repeater_sub_field() lines 299-315 uses an unconditional ancestor loop; telemetry's line 314 is $cursor = $parent in the v3.2.2 source.
- The loop was introduced by commit
1e72ae1c5f8cbdaf5e3aa33b6d0ba969c2b26969 (feat: add ACF repeater field support) and is present in tags v3.2.0, v3.2.1, and v3.2.2.
Engineering notes
The affected code is in the Pro package within the Codeinwp/otter-blocks monorepo, not the Themeisle SDK. The execution path requires an active Pro Dynamic Content integration, ACF availability, a requested ACF field whose direct value is empty, and an ancestor chain returned by ACF that does not reach a missing parent. The telemetry does not expose the ACF field definitions, so the malformed or cyclic hierarchy is inferred from the code path and timeout location rather than directly observed.
A matching unconditional parent walk also exists in Dynamic_Content::get_acf_repeater_sub_field_image() at plugins/otter-pro/inc/plugins/class-dynamic-content.php lines 389-410. That surface was not named by the fatal location and remains a related compatibility case rather than confirmed impact.
Test coverage status
tests/test-dynamic-content.php lines 891-1011 covers collection of already-resolved nested repeater rows, empty collection paths, and image-value collection. No relevant coverage was found during inspection for get_acf_repeater_sub_field() ancestor traversal, cyclic parent references, or repeated ACF parents.
What to verify or explore next
- May be worth reproducing with an ACF field lookup that returns a parent cycle while rendering an ACF Dynamic Content value on the frontend.
- May be worth checking the equivalent image repeater lookup with the same parent sequence.
- If reproducible, run the Dynamic Content PHPUnit suite containing
tests/test-dynamic-content.php against the supported ACF and WordPress combinations.
Unknowns / follow-up
- The affected sites' ACF versions and exact field-parent data were not included in the telemetry.
- It is unknown whether the cyclic response originates from stored ACF configuration, an ACF compatibility change, or another plugin altering
acf_get_field() results.
Confidence
Confidence: 94/100
Production telemetry records 19 frontend fatals on three sites using Otter Pro 3.2.2, and the reported line resolves exactly to an unbounded ACF ancestor traversal in the Pro Dynamic Content code. The loop has no repeated-parent or depth termination condition.
Crash telemetry
|
|
| Occurrences |
19 |
| Distinct sites |
3 |
| First seen |
2026-08-13 17:46 UTC |
| Last seen |
2026-08-15 02:08 UTC |
| Crash location |
product:inc/plugins/class-dynamic-content.php:314 |
| Request context |
frontend |
| Inside Themeisle SDK |
no |
| Product versions |
3.2.2 |
| WP versions |
7.0.4 |
| PHP versions |
8.1.34, 8.4.22 |
| SDK versions |
3.3.58 |
Source: automated crash report — otter-pro, fingerprint 2417ff35ad27ff88fb1d4002af4dba15
Generated by bug-report-triage (ID: bug-report-triage_6a80008f3443b0.07314561)
Summary
Rendering Dynamic Content for an ACF repeater sub-field can terminate the frontend request after PHP reaches its execution-time limit.
Expected behavior: Dynamic Content either resolves the requested repeater sub-field or safely stops when its field hierarchy cannot be traversed.
Actual behavior: The request can run until the configured PHP timeout and produce
Maximum execution time of 900 seconds exceeded.Impact: Affected pages fail to render while the Dynamic Content ACF lookup is evaluated.
Customer context
Maximum execution time of 900 seconds exceededReproduction notes
Reproduction is code-confirmed from the non-terminating traversal; the telemetry does not include the exact ACF configuration needed to recreate the production hierarchy.
Diagnosis
Conclusion
The production location maps exactly to
Dynamic_Content::get_acf_repeater_sub_field()at the cursor reassignment inside itswhile ( true )parent walk. That loop stops only whenacf_get_field()returns no parent and has no repeated-parent or maximum-depth guard. A cyclic ACF field-parent result therefore does not terminate, matching the timeout fatal recorded at line 314.Where this likely occurs
plugins/otter-pro/inc/plugins/class-dynamic-content.php—Dynamic_Content::evaluate_content()lines 45-64 routes ACF Dynamic Content throughget_acf()for frontend rendering when the Pro license hooks are active.plugins/otter-pro/inc/plugins/class-dynamic-content.php—Dynamic_Content::get_acf()lines 240-257 invokesget_acf_repeater_sub_field()when the selected ACF value is empty.plugins/otter-pro/inc/plugins/class-dynamic-content.php—Dynamic_Content::get_acf_repeater_sub_field()lines 299-315 uses an unconditional ancestor loop; telemetry's line 314 is$cursor = $parentin thev3.2.2source.1e72ae1c5f8cbdaf5e3aa33b6d0ba969c2b26969(feat: add ACF repeater field support) and is present in tagsv3.2.0,v3.2.1, andv3.2.2.Engineering notes
The affected code is in the Pro package within the
Codeinwp/otter-blocksmonorepo, not the Themeisle SDK. The execution path requires an active Pro Dynamic Content integration, ACF availability, a requested ACF field whose direct value is empty, and an ancestor chain returned by ACF that does not reach a missing parent. The telemetry does not expose the ACF field definitions, so the malformed or cyclic hierarchy is inferred from the code path and timeout location rather than directly observed.A matching unconditional parent walk also exists in
Dynamic_Content::get_acf_repeater_sub_field_image()atplugins/otter-pro/inc/plugins/class-dynamic-content.phplines 389-410. That surface was not named by the fatal location and remains a related compatibility case rather than confirmed impact.Test coverage status
tests/test-dynamic-content.phplines 891-1011 covers collection of already-resolved nested repeater rows, empty collection paths, and image-value collection. No relevant coverage was found during inspection forget_acf_repeater_sub_field()ancestor traversal, cyclic parent references, or repeated ACF parents.What to verify or explore next
tests/test-dynamic-content.phpagainst the supported ACF and WordPress combinations.Unknowns / follow-up
acf_get_field()results.Confidence
Confidence: 94/100
Production telemetry records 19 frontend fatals on three sites using Otter Pro 3.2.2, and the reported line resolves exactly to an unbounded ACF ancestor traversal in the Pro Dynamic Content code. The loop has no repeated-parent or depth termination condition.
Crash telemetry
product:inc/plugins/class-dynamic-content.php:314Source: automated crash report — otter-pro, fingerprint
2417ff35ad27ff88fb1d4002af4dba15Generated by bug-report-triage (ID: bug-report-triage_6a80008f3443b0.07314561)