Skip to content

Register APS renderer via requestId so it survives Prebid field stripping#963

Open
aram356 wants to merge 2 commits into
issue-764-aps-openrtbfrom
fix/aps-renderer-requestid-registration
Open

Register APS renderer via requestId so it survives Prebid field stripping#963
aram356 wants to merge 2 commits into
issue-764-aps-openrtbfrom
fix/aps-renderer-requestid-registration

Conversation

@aram356

@aram356 aram356 commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Fixes #962. Stacked on #918 (targets issue-764-aps-openrtb).

Problem

APS bid-by-reference renderers never register, so every APS bid renders empty and Prebid throws Missing ad markup or URL (reason noAd).

interpretResponse sets the renderer descriptor on the bid as the custom trustedServerRenderer field; the bidResponse listener registers it into window.tsjs.apsPrebidRenderers keyed by the generated adId. But Prebid drops unknown top-level fields when it normalizes bids during addBidResponse, so the custom field is gone before the listener runs (absent as early as bidAccepted). The listener sees renderer === undefined, returns, and the registry stays empty.

Fix (minimal, additive)

Stash the descriptor keyed by requestId — a first-class field Prebid preserves — when the bids are built, and have the bidResponse listener fall back to that stash when the custom field is absent.

  • interpretResponse (auctionBidsToPrebidBids): if (renderer) stashPendingApsRenderer(requestId, renderer)
  • bidResponse listener: const renderer = bid[APS_RENDERER_FIELD] ?? takePendingApsRenderer(bid['requestId'])
  • Bounded Map (256 entries); take deletes on read.

Additive by design: the existing custom-field path is unchanged, so cases where the field survives (e.g. unit/browser harness) behave exactly as before. The fallback engages only when Prebid has stripped the field. No new dependency; the bridge, descriptor format, server, and render path are untouched.

Verification

  • New unit test: descriptor stashed, custom field removed (simulating Prebid), registration still succeeds via requestId.
  • Full JS suite passes; formatting clean.
  • Validated against a live deployment by serving the built bundle: renderer registrations went from 0 to non-zero, APS noAd failures dropped sharply, and APS creatives rendered in-slot instead of erroring.

aram356 added 2 commits July 23, 2026 19:11
…ping

APS bids are bid-by-reference: interpretResponse sets the renderer descriptor on
the Prebid bid as the custom `trustedServerRenderer` field, and a bidResponse
listener registers it in window.tsjs.apsPrebidRenderers keyed by Prebid's generated
adId so the Universal Creative can later request it.

Prebid normalizes each bid into its own object during addBidResponse and drops
unknown top-level fields, so the custom field can be gone before the bidResponse
listener runs (observed in production: absent as early as bidAccepted). The listener
then saw renderer === undefined and returned without registering, leaving the
registry empty; the Universal Creative's request found nothing and Prebid's default
renderer threw "Missing ad markup or URL" (reason noAd) for every APS bid.

Also stash the descriptor keyed by `requestId` (a first-class field Prebid
preserves) when the bids are built, and have the bidResponse listener fall back to
that stash when the custom field is absent. Additive: the existing field path is
unchanged, so cases where the field survives behave exactly as before; the fallback
engages only when Prebid has stripped it. Bounded map. Adds a unit test that
registers via requestId with the custom field removed.
@aram356 aram356 self-assigned this Jul 24, 2026
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.

1 participant