{"record":{"id":"9be57b29cf8d4b9c","repo":"soimort/you-get","slug":"no-stream-selected","errorCode":null,"errorMessage":"no stream selected","messagePattern":"no stream selected","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"src/you_get/extractors/missevan.py","lineNumber":115,"sourceCode":"\ndef is_covers_stream(stream):\n    stream = stream or ''\n    return stream.lower() in ('covers', 'coversmini')\n\ndef get_file_extension(file_path, default=''):\n    url_parse_result = urllib.parse.urlparse(file_path)\n    _, suffix = os.path.splitext(url_parse_result.path)\n    if suffix:\n        # remove dot\n        suffix = suffix[1:]\n    return suffix or default\n\ndef best_quality_stream_id(streams, stream_types):\n    for stream_type in stream_types:\n        if streams.get(stream_type['id']):\n            return stream_type['id']\n\n    raise AssertionError('no stream selected')\n\n\nclass MissEvanWithStream(VideoExtractor):\n\n    name = 'MissEvan'\n    stream_types = missevan_stream_types\n\n    def __init__(self, *args):\n        super().__init__(*args)\n        self.referer = 'https://www.missevan.com/'\n        self.ua = _UA\n\n    @classmethod\n    def create(cls, title, streams, *, streams_sorted=None):\n        obj = cls()\n        obj.title = title\n        obj.streams.update(streams)\n        streams_sorted = streams_sorted or cls._setup_streams_sorted(streams)","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/soimort/you-get/blob/049548f3f3f35e67ba8d3181c71fdc71d11cf260/src/you_get/extractors/missevan.py#L97-L133","documentation":"best_quality_stream_id walks the MissEvan stream_types preference list and returns the first type id present in the available streams mapping; if none of the preferred ids exist in streams, it raises AssertionError('no stream selected'). This means the API responded, but every advertised quality the extractor knows about is absent for this sound.","triggerScenarios":"A MissEvan track whose streams dict contains only ids not covered by missevan_stream_types (new quality tiers, or empty streams for region/paid-locked audio); calling the helper directly with a streams mapping whose keys don't intersect stream_types ids.","commonSituations":"MissEvan adding a new bitrate/codec tier and deprecating old ids; paid or VIP-only sounds returning an empty stream map; extractor's static stream_types list drifting behind the live API.","solutions":["Dump the streams mapping and stream_types to see which ids are actually available for the failing track","Update the missevan_stream_types list in the extractor to include the new ids returned by the API","If streams is empty, the track is likely paid/region-locked — try another track or a logged-in session","Pass an explicit stream id/quality kwarg if the caller supports selection, bypassing 'best' selection"],"exampleFix":"# before\ndef best_quality_stream_id(streams, stream_types):\n    for stream_type in stream_types:\n        if streams.get(stream_type['id']):\n            return stream_type['id']\n    raise AssertionError('no stream selected')\n\n# after (fall back to any available stream)\ndef best_quality_stream_id(streams, stream_types):\n    for stream_type in stream_types:\n        if streams.get(stream_type['id']):\n            return stream_type['id']\n    if streams:\n        return next(iter(streams))\n    raise AssertionError('no stream selected')","handlingStrategy":"fallback","validationCode":"def missevan_pick_stream(streams, stream_types):\n    for st in stream_types:\n        if streams.get(st['id']):\n            return st['id']\n    return next(iter(streams), None)  # None signals nothing available","typeGuard":null,"tryCatchPattern":"try:\n    missevan_download(url, ...)\nexcept AssertionError as e:\n    if 'no stream selected' in str(e):\n        print('track has no known quality tiers; likely paid/region-locked')\n    else:\n        raise","preventionTips":["Inspect the streams mapping returned by the API before assuming a quality exists","Update the static stream_types list when MissEvan ships new tiers","Empty streams usually means access-restricted audio — check entitlement, not code"],"tags":["missevan","stream-selection","api-drift"],"backgroundTag":null,"analyzedSha":"049548f3f3f35e67ba8d3181c71fdc71d11cf260","analyzedAt":"2026-08-15T03:58:15.069Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}