Skip to content

fix(sdk): a delete is kept hidden when any script lookup could reach it, not only an id - #6165

Merged
miguel-heygen merged 2 commits into
mainfrom
fix/sdk-script-lookups-any-selector
Oct 24, 2026
Merged

miguel-heygen merged 2 commits into
mainfrom
fix/sdk-script-lookups-any-selector

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

#6143 keeps a deleted node as a hidden copy when an inline script looks it up, so the script does not throw before its timeline registers. It only recognised a literal getElementById('x') or querySelector('#x'). A script that looks the node up by class (.halftone-svg), by tag or attribute selector, or through a variable (document.querySelector(path) over a list of selectors, getElementById(id) in a helper) still lost the node, threw, and the render failed.

scriptLooksUp now keeps the delete hidden when any lookup in the page's inline scripts could reach the node or something inside it:

  • a literal id, class name, tag name or selector is tested against the node and its descendants (matches / querySelector);
  • a lookup whose argument is not a literal can name any node, so every delete is kept;
  • a selector with a template placeholder is kept.

Cost: a page with such a script keeps hidden copies of nodes the person deleted. The copies are display: none and carry no media sources (separate change), so the render does not paint or fetch them.

Why standalone and under the size floor: it touches only the lookup scan and is independent of the media-source change.

Evidence

31 renders of stored compositions with their draft overrides, from one week of failures that a literal id scan did not explain. Each was replayed with the SDK, then loaded in a real browser and its page errors counted.

page errors
original compositions, no overrides 0 of 31
replayed with main 18 of 31
replayed with this change 1 of 31 (a syntax error in the composition's own script, not a lookup)

12 distinct compositions from that set rendered with the CLI after the change, all exit 0, 6 to 44 s.

Tests

apply-patches.scriptTargets.test.ts: a delete is hidden when the script looks it up by class (querySelector and getElementsByClassName) or through a variable (selector list, id variable); a delete no lookup can reach is still removed. The first two fail on main. Full SDK suite 667 tests green three runs in a row.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES · 1 blocker · 1 important · 0 nits · head 936e27d9

The class/tag/selector widening is right, but an argument that starts with a literal and continues with an expression is neither "literal" nor "dynamic" here, so the most common generated lookup shape still loses its node. ↓ inline

Scope

Read scriptLookups.ts and the test diff end to end. Ran src/engine/ (229 tests, green) and probed scriptLooksUp directly against a node <div id="word-3" class="item-3 w">:

script kept
getElementById('word-' + i) false
querySelector('#word-' + i) false
getElementsByClassName(\item-${i}`)` false
querySelector(\#word-${i}`)/getElementById(`word-${i}`)` true
querySelectorAll('.w') true
getElementById('nope') false

Mergeability: GitHub reports DIRTY — a test-only append conflict in apply-patches.scriptTargets.test.ts with #6163, so no Actions run exists for this head. Needs a rebase before CI can gate it.

Comment thread packages/sdk/src/engine/scriptLookups.ts
Comment thread packages/sdk/src/engine/scriptLookups.ts
@miguel-heygen
miguel-heygen force-pushed the fix/sdk-script-lookups-any-selector branch from 936e27d to ae5830a Compare October 24, 2026 00:18
@miguel-heygen

Copy link
Copy Markdown
Collaborator Author

Head ae5830a, rebased on main (#6163 landed), one line per point:

  • Blocker (literal continued by an expression, 'word-' + i, '#item-' + n, .concat(n)): fixed. A lookup counts as literal only when the closing quote is followed by ); anything else keeps the delete hidden. Tests for all three shapes fail on the previous head.
  • Important (placeholder in getElementsByClassName / getElementsByTagName): fixed. A template placeholder in any lookup keeps the delete hidden, tested for both.
  • Conflict with base: resolved in the rebase; the SDK suite (671 tests) is green three runs in a row.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE — 2 resolved, 0 open, 0 new · 936e27d → ae5830a

@github-actions

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 143 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

Unstable (1)

  • seqheldtwice-tlhold-px-r0-root-z100: tracking 120.29, pressJump 312.3, drop 0, reload 0, render 0.02, renderKey -, undo true, teleport false / tracking 0.41, pressJump 0.11, drop 0.35, reload 0.35, render 0.02, renderKey -, undo true, teleport true / tracking 0.41, pressJump 0.11, drop 0.35, reload 0.35, render 0.02, renderKey -, undo true, teleport true

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 24, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 24, 2026
@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 8a102f6 Oct 24, 2026
66 checks passed
@miguel-heygen
miguel-heygen deleted the fix/sdk-script-lookups-any-selector branch October 24, 2026 02:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant