YouTube's 2026 poToken/BotGuard enforcement now rejects the pot-less ANDROID
client outright (playabilityStatus "sign in to confirm you're not a bot"), which
aborted the whole extraction since ANDROID was the required primary.
stream_info_with() now cascades ANDROID -> VISIONOS for the primary player
response: when ANDROID is unusable (fetch error, failed playability, or decoy),
retry with VISIONOS (client 101) as the primary. VISIONOS is pot-free,
visitorData-based, and needs no JS player -- the current survivor (yt-dlp
default; NewPipeExtractor #1508). Only if VISIONOS also fails do we surface the
ORIGINAL ANDROID error (keeps the real bot-wall reason visible).
The fallback drops the (poisoned) visitorData cache first so VISIONOS mints a
fresh one (the ingredient that passes attestation). On the VISIONOS-primary
path the primary source carries no poToken (null) and uses the VISIONOS cpn, so
no ANDROID pot/cpn is appended to a visionOS URL (would 403); the redundant
add-on VISIONOS fetch is skipped. Output shape is unchanged (still the muxed
itag-18 the app plays) -- no app or delivery-labeling change. 5 new unit tests.