Skip to content

Bug: data-color-grading renders solid white (mp4) / black (prores) frames — any grading, 0.7.109 & 0.8.2 #3329

Closed

Description

@xinzhuzi

Bug: data-color-grading renders solid white (mp4) or black (prores) frames — both 0.7.109 and 0.8.2

Environment

  • hyperframes CLI 0.7.109 and 0.8.2 (both tested, identical behavior)
  • macOS arm64 (Darwin 25.4.0)
  • Static <img> with data-color-grading applied via hyperframes media-treatment --apply

Reproduction

  1. Create a composition with a full-frame <img> (with id for strict lint):
<img id="media-frame" class="clip" src="frame.png" data-start="0" data-duration="1" data-track-index="1" style="left:50%;top:50%;width:1920px;height:1080px;object-fit:cover;">
  1. Apply a grading patch:
hyperframes media-treatment --project . --file index.html --selector "img#media-frame" --grading '{"effects":{"kuwahara":0.8}}' --apply
  1. Render:
hyperframes render . --format mp4 --output out.mp4 --fps 30 --quiet --strict-all

Results (4-condition matrix)

Condition Output Luminance
effects.kuwahara=0.8 + mp4 Solid white frame 252/255
adjust.saturation=-0.3 + mp4 Solid white frame 251/255
effects.kuwahara=0.8 + mov (prores) Solid black frame 0/255
No data-color-grading + mp4 ✅ Normal image 96/255 (matches source)

Expected

The graded image should render with the color treatment applied, not a solid color frame.

Key observations

  • Any data-color-grading attribute (regardless of effect type: effects.* or adjust.*) triggers the bug
  • Removing the data-color-grading attribute restores normal rendering
  • Bug is identical across 0.7.109 and 0.8.2
  • The CLI --apply succeeds (ok: true) and writes a complete ~80-key data-color-grading JSON to the element
  • The composition HTML skeleton uses #stage with data-composition-id, data-no-timeline, data-start/duration/width/height/fps — worker-standard structure

Reproduction package

A tarball with the minimal project (HTML + frame + 4 rendered outputs) is available. The command sequence above reproduces it from scratch.

Impact

This blocks the "deterministic media treatment" pipeline for any project that renders graded media through the standard composition path.

Activity

  1. miguel-heygen commented on Aug 18, 2026

    @miguel-heygen
    Collaborator

    Thanks for the detailed matrix. We tried to reproduce this on current HyperFrames 0.8.3 using both GitHub-hosted macos-14 M1/arm64 and Linux. The ungraded control, adjustment-only grading, and Kuwahara grading all remained non-solid through runtime capture, raw frames, H.264 MP4, ProRes MOV, and HEVC. We therefore do not yet have a product RED or a first corrupt boundary to patch safely.

    Could you please attach or link the sanitized minimal tarball mentioned in the report, including the original frame.png, index.html after media-treatment --apply, and one failing output? If the source cannot be public, a newly generated minimal source with the same failure is enough.

    Please also retry once with npx hyperframes@0.8.3 and share:

    1. The exact render command and whether MP4, ProRes, or both still become solid.
    2. npx hyperframes@0.8.3 doctor --json output.
    3. ffmpeg -version output.
    4. Whether frame.png has alpha, an ICC profile, Display-P3/wide-gamut metadata, or unusual bit depth.
    5. One extracted failing frame and its SHA-256.

    We added a test-only macOS arm64 reproduction gate in draft PR #3330 so the issue can be pinned as soon as the missing source condition is identified. We will not invent a color-grading fix without a reproducing boundary.

  2. xinzhuzi commented on Aug 19, 2026

    @xinzhuzi
    Author

    Update — narrowed down the trigger: it's not "any grading", it's grading on an element with a CSS entrance animation.

    Further bisection (same env: HY 0.7.109, chrome-headless-shell, macOS arm64):

    case result
    single <img data-color-grading='{"adjust":{"exposure":0.2}}'>, no CSS animation ✅ renders correctly
    same element + the full default grading payload (tapeNoise/halftone/kuwahara non-zero), no CSS animation ✅ renders correctly
    same element + any grading + animation: hf-in .24s ease-out forwards (keyframes animating opacity: 0 → 1 + transform) ❌ solid white (mp4) / black (prores)
    original repro project (all graded elements carry an entrance-animation class) ❌ still reproduces today

    Minimal repro:

    <style>
    .clip { opacity: 0; animation: hf-in .24s ease-out forwards; }
    @keyframes hf-in { from { opacity: 0; transform: translate(-50%,-50%) scale(.96); } to { opacity: 1; transform: translate(-50%,-50%) scale(1); } }
    </style>
    <img data-color-grading='{"adjust":{"exposure":0.2}}' class="clip" src="frame.png" ...>

    Remove class="clip" (or the animation) and the same grading payload renders fine. Duration (1 frame vs 30) and the grading payload contents make no difference.

    Hypothesis: the grading capture pass reads the element at the animation's initial state (opacity 0 / mid-composite) and produces empty pixels for the graded layer.

    Workaround: don't put data-color-grading on elements that also carry a CSS entrance animation (apply grading to a wrapper, or drop the animation on graded elements).

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions