fix: guard input-template render effect against unstable content - #7
Merged
Merged
Conversation
The effect syncing rendered input-template content whenever
renderingContext changes always wrote the freshly-rendered content
back via onUnitInputRenderedUpdate, even when it matched what was
already stored. onUnitInputRenderedUpdate always produces a new unit
object, which can cause renderingContext to be recomputed upstream
and re-fire this same effect - for any input whose rendered output
isn't stable across renders, this creates an infinite update loop
("Maximum update depth exceeded"), reproduced when selecting the
pp.x/average.x executables in the unit editor. Only write back when
the rendered content actually changed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ExecutionUnit's effect that re-renders input-template content wheneverrenderingContextchanges always wrote the freshly-rendered content back viaonUnitInputRenderedUpdate, even when it exactly matched what was already stored:onUnitInputRenderedUpdatealways produces a brand-newunitobject viaonUpdate(...). If anything upstream recomputesrenderingContextfrom the updated unit (even to a referentially-new-but-otherwise-equal value), this effect re-fires — and for any input whose rendered output isn't perfectly stable across renders, this creates an infiniterenderingContext→onUpdate→ newrenderingContextloop, crashing with React's "Maximum update depth exceeded".Reproduced live: selecting the
pp.xoraverage.xexecutables (unlike the defaultpw.x) in the unit editor crashes the whole app with this exact error, immediately on opening the Flavor select.Fix
Only call
onUnitInputRenderedUpdatewhen the newly-rendered content actually differs frominputRow.rendered, breaking the loop regardless of why a given input's rendered output is unstable.Test plan
npm run buildandnpm test(20/20 passing)unit-editor-choose-espresso-executable-and-flavor.feature, examples usingpp.x/average.x)🤖 Generated with Claude Code