Skip to content

feat(lint): error when a video or img src is the other media kind - #3609

Merged
xuanruli merged 1 commit into
mainfrom
xuanru/lint-media-src-kind
Sep 3, 2026
Merged

feat(lint): error when a video or img src is the other media kind#3609
xuanruli merged 1 commit into
mainfrom
xuanru/lint-media-src-kind

Conversation

@xuanruli

@xuanruli xuanruli commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What

Add a media_src_kind_mismatch lint error when a <video> element's own src is an image, or an <img> element's own src is a video.

Why

The existing media-src check only asks whether src is a resolvable URL, so <video src="still.jpg"> and <img src="clip.mov"> lint green. Agents then ship that HTML; the producer later fail-closes because the tag and file kind disagree.

Companion bake-time rewrite (does not live here): https://github.com/heygen-com/experiment-framework/pull/49536

How

Classify the element's own src from data: MIME or file extension. This rule is an error, so it only fires on cases that cannot be a false positive:

  • <video src> whose path/MIME is an image
  • <img src> whose path/MIME is a video

Skipped on purpose (extension cannot prove a producer failure): blob:, extensionless URLs, <audio> (including <audio src="*.mp4"> SFX), and <source>.

Test plan

  • Unit tests added/updated (packages/lint/src/rules/media.test.ts: video+jpg, img+mov, data:image, matching kinds, extensionless + audio)
  • Manual testing performed
  • Documentation updated (if applicable)

Made with Cursor

Agents were shipping <video src="….jpg"> / <img src="….mov"> because the existing URL-resolvable check stayed green. Report an error so the agent rewrites the tag; skip audio, <source>, and extensionless URLs.
@xuanruli
xuanruli marked this pull request as ready for review September 3, 2026 04:49

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed at exact head 692580de744f2199426bedeba3ebe2f00d481d44.

  • packages/lint/src/rules/media.ts:44-130 keeps the rule on the provable cases only: element-owned <video>/<img> src, closed image/video suffix sets, data MIME support, case-folding, query/hash stripping, and explicit fail-open for blob/extensionless input. The suffix vocabulary matches EF's shared get_resource_type_from_extension image/video sets today.
  • The finding reconstructs a bounded diagnostic without echoing the full src, is severity error, and leaves <audio>/<source> to their separate policies.
  • media.test.ts:799-868 discriminates both mismatch directions, data-image input, healthy matches, and the extensionless/audio carve-outs. Exact-head CI has zero non-passing checks.

Non-blocking: the suffix vocabulary is still manually duplicated across OSS and EF, so a parity fixture would be useful if either set grows.

Verdict: APPROVE
Reasoning: The rule fails only on extension/MIME evidence that proves a tag-kind mismatch, covers both directions, and preserves the intended ambiguous-source carve-outs.

— Magi

@xuanruli
xuanruli merged commit 8fade97 into main Sep 3, 2026
70 of 71 checks passed
@xuanruli
xuanruli deleted the xuanru/lint-media-src-kind branch September 3, 2026 05:25
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.

2 participants