Skip to content

Unrelated SDK style edits discard earlier important declarations #6267

Open

Description

@AksharP5

Describe the bug

Changing only an element's opacity with the SDK can permanently change its color. When the inline style contains an earlier !important declaration followed by an ordinary declaration of the same property, the SDK reads the ordinary value and writes it back during the unrelated edit. Saving, reopening and undoing the opacity edit keep the wrong color.

Minimal reproduction

Run this in a project using @hyperframes/sdk@0.8.193:

import { openComposition } from "@hyperframes/sdk";

const html = `<!doctype html><html><body>
  <h1 data-hf-id="hf-title"
      style="color: red !important; color: blue; font-size: 48px">
    Release notes
  </h1>
</body></html>`;

const comp = await openComposition(html, { coalesceMs: 0 });
comp.setStyle("hf-title", { opacity: "0.5" });
console.log(comp.serialize());
comp.undo();
console.log(comp.serialize());
comp.dispose();

Steps to reproduce

  1. Open the HTML above. Its text renders red in Chrome because the earlier declaration is important.
  2. Change opacity with setStyle() and serialize the composition.
  3. Inspect the serialized style or reopen it in the browser.
  4. Undo the opacity edit and inspect the result again.

Expected behavior

The text remains red after the opacity edit, persistence, reopening and undo. The unrelated edit must preserve the declaration that determines its color.

Actual behavior

Stage Inline style Computed color
Authored HTML color: red !important; color: blue; font-size: 48px rgb(255, 0, 0)
Opacity edit color: blue; font-size: 48px; opacity: 0.5 rgb(0, 0, 255)
Undo color: blue; font-size: 48px rgb(0, 0, 255)

The public element snapshot already reports blue before the edit. The patch stream records only opacity, so history cannot recover the lost color. The same loss survives the memory persistence adapter and a cancelled batch.

Environment

  • SDK, core and parsers: published 0.8.193, with tarball integrity verified.
  • Reproduced on main f21c3e3e7e8387ec9638cac2179f39c630ffabcf and independently verified with the exact latest-base model on 6e77d783c7c19fa0c5c3833b7cf23d70fb14b70f.
  • Linux x64, Bun 1.4.4, Node 26.11.1, Chrome 152.0.7977.42.

Published package probes reused compatible external dependencies in isolation; this was not a clean consumer installation.

The reproduction uses valid inline CSS and the documented standalone SDK editing flow. No Studio UI or video render is needed.

Related work

SDK parser and parity work in #1350, #1565 and #5246 was checked, including reviews. The shorthand/longhand ordering case discussed in #1550 is separate from this duplicate-priority loss.

Activity

  1. miguel-heygen commented on Oct 25, 2026

    @miguel-heygen
    Collaborator

    Thanks for the clear repro. I can reproduce it with the latest published @hyperframes/sdk 0.8.194: after setStyle("hf-title", { opacity: "0.5" }) the serialized style is color: blue; font-size: 48px; opacity: 0.5, and after undo() it stays color: blue; font-size: 48px.

    The cause is parseStyleAttr in packages/sdk/src/engine/model.ts. It keeps the last declaration of each property regardless of !important, and setStyle writes that whole map back, so any style edit on the element drops the earlier important declaration. Undo can't restore it because the edit only records the property that changed.

    #6268 fixes it in that function and is the one to follow.

  2. added
    bugSomething isn't working
    triage/readyAccepted scope, current evidence, acceptance criteria, and validation path are recorded.
    on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriage/readyAccepted scope, current evidence, acceptance criteria, and validation path are recorded.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions