Skip to content

Build1 publisher3 min readPublished

Schema validators pass the AdCOM extension whose label contradicts its child

IAB Tech Lab's July 2026 portfolio signaling puts each AdCOM signal in its own extension node with a type attribute naming it, and the SSAI stitchers downstream decide what to read from that attribute.

The Engineer · Build desk

Illustration accompanying Schema validators pass the AdCOM extension whose label contradicts its child

What happened

  • The CTV Ad Portfolio signaling IAB Tech Lab finalized in July 2026 round-trips four AdCOM enumerations inside the VAST creative: plcmt, pos, playbackmethod and attr, each in its own extension node.
  • In the canonical form the type attribute names the signal the extension carries, and the single child element repeats that name and holds the integer value.
  • A pause buy that carried video.plcmt=5 in OpenRTB shipped with that integer inside an extension labelled type="pos", and format reporting came back as squeezeback geometry or empty.
  • Schema validation checks nesting and text content, and does not require type="plcmt" when the only child is a plcmt element, so pipelines green-light the mislabelled block.
  • The portfolio rule pack flags exactly this case as VAST-4.4-adcom-extension-type-mismatch, and the rule text says downstream stitchers key off type to decide what to read.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure The vendors producing the buyer's format numbers sit downstream of the auction and often never see the bid request, so a pause placement labelled as geometry is the only record they have to count from.
  • constraint An XSD pass cannot be the gate for portfolio tags, because the defect is a legal attribute on a legal parent; the check has to compare the wrapper label against the child name.
  • decision QA for pause and overlay creative moves out of human review of four near-identical blocks and into a rule pack run on fixtures, which the trafficking team has to maintain.
  • precedent Teams that still serve players without VAST 4.x NonLinear support end up maintaining two extension conventions for the same creative, each with its own binding and media file rules.

A stitcher that receives `<Extension type="pos" ext="adcom"><plcmt>5</plcmt></Extension>` reads the attribute first. It records the payload as screen position, or it drops the block because the inner tag does not match the signal the wrapper declared [7]. Both outcomes happen before anything reads the integer, and the integer was right: 5 is Pause [6].

The attribute carries the meaning because the VAST response outlives the bid request. SSAI stitchers and measurement vendors sitting downstream of the auction often never see OpenRTB at all, and they learn what was sold from the creative envelope [9]. Portfolio guidance treats `type` as the selector [11]. The canonical block for a pause placement is `<Extension type="plcmt" ext="adcom"><plcmt>5</plcmt></Extension>` [4].

Four legal strings in the attribute and four legal child tags give 16 pairings. Four agree, so 12 mislabel the signal with nesting that is still legal [23]. Twelve is a lot of ways to spell one attribute wrong. A fifth string is a separate defect: `type="loudness"`, or anything outside the four names, trips `VAST-4.4-adcom-extension-unknown-signal` [13]. A swap between two real AdCOM field names is the quiet case, because both strings exist in the spec [14].

Correct labels do not make the numbers agree. A tag carrying `plcmt=5` next to `playbackmethod=1` can have four structurally perfect wrappers while the integers describe incompatible formats [15]. The portfolio guide maps Pause, Screensaver, Overlay, Squeezeback and In-Scene to the signal combinations each format allows, and the value-level check is whether the integers inside correctly labelled extensions sit in the same row of that table [16].

Nothing exotic puts the wrong attribute on the wrapper. Copy-paste from an older template, a merge conflict in a trafficking UI, or one swapped attribute on export is enough, and every integer stays in range [17]. The write-up, published on dev.to under the handle aleksuix [24], starts QA in the browser: paste the live ad tag URL or the resolved InLine XML into a tag tester that fetches wrappers, previews the NonLinear or video asset, and runs the portfolio rule pack alongside generic VAST checks [18]. For a pause or overlay buy the author confirms the render path and the AdCOM extensions in the same pass, not only that an MP4 bit rate exists [25]. Chained tags go through an inspector that walks each redirect, validates every hop, and shows where the InLine with the extensions actually lands [19]. Fixtures then run under `vastlint check` in CI, where according to the post the type mismatch warning survives better than eyeballing four nearly identical extension blocks [21].

One caution on the tooling: the IAB-style tester with SIMID studio and sample creatives is an independent fork, not an IAB Tech Lab product [20]. And the four adcom nodes are not the whole surface for a portfolio buy. Legacy players that never implemented VAST 4.x NonLinear still expect the portfolio creative inside `<Extension type="ctv_ad_portfolio">`, a path that binds by creative id and carries its own required MediaFiles rules [22].

What to watch

  • Whether SSAI and measurement vendors publish what they actually do with a block whose type and child disagree: drop it, or file it under the declared signal.
  • Whether the type-mismatch check appears in validators other than the linter the write-up uses.
  • Whether the rule pack gains a value-level check that tests signal combinations against the format table rows, not just the wrapper labels.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories