Skip to content

Plan V2 rejects valid video metadata when ffprobe reports only some color fields #2807

Description

@JonathanRosado

Describe the bug

Plan Protocol V2 cannot plan an otherwise valid SDR video when ffprobe reports one color field but omits the others. The engine intentionally normalizes absent components to empty strings, but planV2.ts validates all three components with the generic non-empty-string reader.

Observed error:

[planV2] meta/videos.json.extracted[3].metadata.colorTransfer must be a non-empty string

Plan V1/local rendering accepts the same source. This is a metadata-validation mismatch only; the media decodes and renders correctly.

Link to reproduction

https://github.com/heygen-com/hyperframes/tree/v0.7.72/packages/producer

Steps to reproduce

Create an H.264 file whose stream declares the matrix but not transfer/primaries:

ffmpeg -f lavfi -i 'color=c=gray:s=320x180:r=24:d=1' \
  -c:v libx264 -pix_fmt yuv420p -colorspace bt709 -an partial-color.mp4

ffprobe -v error -select_streams v:0 \
  -show_entries stream=codec_name,pix_fmt,color_space,color_transfer,color_primaries \
  -of json partial-color.mp4

The stream is valid. ffprobe returns color_space: "bt709" while omitting color_transfer and color_primaries.

Use the file in a <video> and run distributed planning with PlanProtocol: "v2" (or create a V1 plan and call createPlanV2FromV1). The engine writes:

"colorSpace": {
  "colorTransfer": "",
  "colorPrimaries": "",
  "colorSpace": "bt709"
}

createPlanV2FromV1 then throws because readVideoMetadata() calls readString() for every component.

The source-level contradiction is visible at v0.7.72: the engine's ffprobe adapter uses videoStream.color_transfer || "", while the Plan V2 reader requires the field to be non-empty.

Expected behavior

V2 accepts each color component as a string, including "" for an ffprobe-omitted component, while retaining null when no color metadata exists at all. Output behavior should match V1.

Actual behavior

Planning aborts before publication with PlanV2IntegrityError, even though the file is valid SDR and decodable.

Environment

HyperFrames: 0.7.72
Commit: 72ae39e3d052a185fd0890eccac0085dc9fac60d
Runtime: GCP Cloud Run Gen2, Linux x86_64
Node image: node:22-bookworm-slim
Service shape: 4 vCPU / 16 GiB
Real input: H.264, yuv420p, 1920x1080, 24 CFR

The production failure occurred with ffprobe reporting color_space=bt709 and empty transfer/primaries. No decode or pixel-path change was needed to render the file successfully.

Suggested narrow fix

In packages/producer/src/services/distributed/planV2.ts, use a string-type validator that permits "" only for colorTransfer, colorPrimaries, and colorSpace; keep the generic non-empty validator everywhere else. Add a regression with partial ffprobe metadata.

We validated that scope in a compatibility image: validator-only, no color conversion, decode, or pixel-path changes.

Duplicate search

No matching issue or PR was found:

The Plan V2 PR chain, including #2788, contains no fix for this validation mismatch.

Metadata

Metadata

Assignees

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