ytdl-org/youtube-dl · error · ExtractorError
Invalid url for track %d of album url %s
Error message
Invalid url for track %d of album url %s
What it means
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.
Source
Thrown at youtube_dl/extractor/audiomack.py:131
def _real_extract(self, url):
# URLs end with [uploader name]/album/[uploader title]
# this title is whatever the user types in, and is rarely
# the proper song title. Real metadata is in the api response
album_url_tag = self._match_id(url).replace('/album/', '/')
result = {'_type': 'playlist', 'entries': []}
# There is no one endpoint for album metadata - instead it is included/repeated in each song's metadata
# Therefore we don't know how many songs the album has and must infi-loop until failure
for track_no in itertools.count():
# Get song's metadata
api_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,
note='Querying song information (%d)' % (track_no + 1))
# Total failure, only occurs when url is totally wrong
# Won't happen in middle of valid playlist (next case)
if 'url' not in api_response or 'error' in api_response:
raise ExtractorError('Invalid url for track %d of album url %s' % (track_no, url))
# URL is good but song id doesn't exist - usually means end of playlist
elif not api_response['url']:
break
else:
# Pull out the album metadata and add to result (if it exists)
for resultkey, apikey in [('id', 'album_id'), ('title', 'album_title')]:
if apikey in api_response and resultkey not in result:
result[resultkey] = compat_str(api_response[apikey])
song_id = url_basename(api_response['url']).rpartition('.')[0]
result['entries'].append({
'id': compat_str(api_response.get('id', song_id)),
'uploader': api_response.get('artist'),
'title': api_response.get('title', song_id),
'url': api_response['url'],
})
return result
View on GitHub (pinned to 956b8c5855)
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.
Example fix
// before
api_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, ...)
if 'url' not in api_response or 'error' in api_response:
raise ExtractorError('Invalid url for track %d of album url %s' % (track_no, url))
// after: validate the first response before entering the loop, so a bad tag fails fast with a clearer message
if track_no == 0 and ('url' not in api_response or 'error' in api_response):
raise ExtractorError('Invalid album url %s: API returned %r' % (url, api_response), expected=True)
if 'url' not in api_response or 'error' in api_response:
raise ExtractorError('Invalid url for track %d of album url %s' % (track_no, url)) Defensive patterns
Strategy: validation
Validate before calling
import json, time, urllib.request
def audiomack_album_ok(album_url_tag):
api = 'http://www.audiomack.com/api/music/url/album/%s/0?extended=1&_=%d' % (album_url_tag, time.time())
try:
data = json.load(urllib.request.urlopen(api))
except Exception:
return False
return isinstance(data, dict) and data.get('url') and 'error' not in data Type guard
def is_valid_audiomack_track_response(r):
return isinstance(r, dict) and 'url' in r and 'error' not in r Try / catch
from youtube_dl.utils import ExtractorError
try:
ydl.extract_info(audiomack_url)
except ExtractorError as e:
if 'Invalid url for track' in str(e):
# album tag is wrong or API schema changed; do not retry blindly
raise ValueError('Audiomack album tag invalid: %s' % audiomack_url) from e
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The page doesn't contain any tracks
- Invalid URL
- Invalid URL
- %s said: %s
- %s: No songs found, try using proxy
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/6d6543ded37ba684.
Report an issue: GitHub.