{"record":{"id":"6d6543ded37ba684","repo":"ytdl-org/youtube-dl","slug":"invalid-url-for-track-d-of-album-url-s","errorCode":null,"errorMessage":"Invalid url for track %d of album url %s","messagePattern":"Invalid url for track (.+?) of album url (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/audiomack.py","lineNumber":131,"sourceCode":"    def _real_extract(self, url):\n        # URLs end with [uploader name]/album/[uploader title]\n        # this title is whatever the user types in, and is rarely\n        # the proper song title.  Real metadata is in the api response\n        album_url_tag = self._match_id(url).replace('/album/', '/')\n        result = {'_type': 'playlist', 'entries': []}\n        # There is no one endpoint for album metadata - instead it is included/repeated in each song's metadata\n        # Therefore we don't know how many songs the album has and must infi-loop until failure\n        for track_no in itertools.count():\n            # Get song's metadata\n            api_response = self._download_json(\n                'http://www.audiomack.com/api/music/url/album/%s/%d?extended=1&_=%d'\n                % (album_url_tag, track_no, time.time()), album_url_tag,\n                note='Querying song information (%d)' % (track_no + 1))\n\n            # Total failure, only occurs when url is totally wrong\n            # Won't happen in middle of valid playlist (next case)\n            if 'url' not in api_response or 'error' in api_response:\n                raise ExtractorError('Invalid url for track %d of album url %s' % (track_no, url))\n            # URL is good but song id doesn't exist - usually means end of playlist\n            elif not api_response['url']:\n                break\n            else:\n                # Pull out the album metadata and add to result (if it exists)\n                for resultkey, apikey in [('id', 'album_id'), ('title', 'album_title')]:\n                    if apikey in api_response and resultkey not in result:\n                        result[resultkey] = compat_str(api_response[apikey])\n                song_id = url_basename(api_response['url']).rpartition('.')[0]\n                result['entries'].append({\n                    'id': compat_str(api_response.get('id', song_id)),\n                    'uploader': api_response.get('artist'),\n                    'title': api_response.get('title', song_id),\n                    'url': api_response['url'],\n                })\n        return result\n","sourceCodeStart":113,"sourceCodeEnd":148,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/audiomack.py#L113-L148","documentation":"Raised by BandcampAlbumIE-style album crawling in the Audiomack extractor when the per-track album API endpoint (api/music/url/album/<tag>/<track_no>) returns a JSON object with no 'url' key or with an 'error' key. Because Audiomack has no single album-metadata endpoint, the extractor loops itertools.count() querying each track until failure; this particular failure means the album URL tag itself is wrong, not merely the end of the playlist (end-of-playlist is signaled by 'url' being empty/None). It is raised as a hard ExtractorError, so the whole album extraction aborts.","triggerScenarios":"Calling the audiomack album/playlist extractor with an album_url_tag that does not exist (API responds {'error': ...} or omits 'url' on track 0), or when the site changes its api/music/url/album response schema so 'url' disappears from every response. Any track_no where the response has 'error' set or lacks 'url' triggers it immediately.","commonSituations":"Typo'd or stale album URL pasted from an old page; album deleted from Audiomack so the tag no longer resolves; Audiomack API schema change (renamed 'url' field or new error envelope); using an uploader name where an album tag is expected because the _VALID_URL groups were misparsed.","solutions":["Verify the album URL in a browser: open http://www.audiomack.com/api/music/url/album/<tag>/0?extended=1 and confirm the JSON contains a non-empty 'url' key.","If the API returns an error envelope, the album tag is wrong or removed — find the current album page URL and re-run with its tag.","If the API JSON shape changed (e.g. 'url' renamed), update the check in _real_extract to match the new schema (audiomack.py:131) and report the breakage upstream.","Distinguish this from the normal end-of-playlist case: end-of-album yields {'url': None} (break), so only a missing/erroring first response means a genuinely invalid URL."],"exampleFix":"// before\napi_response = self._download_json('http://www.audiomack.com/api/music/url/album/%s/%d?extended=1&_=%d' % (album_url_tag, track_no, time.time()), album_url_tag, ...)\nif 'url' not in api_response or 'error' in api_response:\n    raise ExtractorError('Invalid url for track %d of album url %s' % (track_no, url))\n\n// after: validate the first response before entering the loop, so a bad tag fails fast with a clearer message\nif track_no == 0 and ('url' not in api_response or 'error' in api_response):\n    raise ExtractorError('Invalid album url %s: API returned %r' % (url, api_response), expected=True)\nif 'url' not in api_response or 'error' in api_response:\n    raise ExtractorError('Invalid url for track %d of album url %s' % (track_no, url))","handlingStrategy":"validation","validationCode":"import json, time, urllib.request\n\ndef audiomack_album_ok(album_url_tag):\n    api = 'http://www.audiomack.com/api/music/url/album/%s/0?extended=1&_=%d' % (album_url_tag, time.time())\n    try:\n        data = json.load(urllib.request.urlopen(api))\n    except Exception:\n        return False\n    return isinstance(data, dict) and data.get('url') and 'error' not in data","typeGuard":"def is_valid_audiomack_track_response(r):\n    return isinstance(r, dict) and 'url' in r and 'error' not in r","tryCatchPattern":"from youtube_dl.utils import ExtractorError\ntry:\n    ydl.extract_info(audiomack_url)\nexcept ExtractorError as e:\n    if 'Invalid url for track' in str(e):\n        # album tag is wrong or API schema changed; do not retry blindly\n        raise ValueError('Audiomack album tag invalid: %s' % audiomack_url) from e\n    raise","preventionTips":["Take album_url_tag from the canonical album page URL, not from copy-pasted partial links.","Probe the track-0 API endpoint before starting a batch over many albums.","Treat any response lacking a non-empty 'url' on track 0 as a dead album rather than retrying."],"tags":["audiomack","api-response","playlist","extractor","invalid-url"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}