soimort/you-get · warning · ValueError

%s is paid item

Error message

%s is paid item

What it means

The Ximalaya tracks API returned is_paid: true with is_free falsy, meaning the audio requires purchase; without a paid session there is no playable stream, so the extractor raises ValueError('%s is paid item') instead of attempting a download that would fail opaquely.

Source

Thrown at src/you_get/extractors/ximalaya.py:25

import json
import re

stream_types = [
        {'itag': '1', 'container': 'm4a', 'bitrate': 'default'},
        {'itag': '2', 'container': 'm4a', 'bitrate': '32'},
        {'itag': '3', 'container': 'm4a', 'bitrate': '64'}
        ]

def ximalaya_download_by_id(id, title = None, output_dir = '.', info_only = False, stream_id = None):
    BASE_URL = 'http://www.ximalaya.com/tracks/'
    json_url = BASE_URL + id + '.json'
    json_data = json.loads(get_content(json_url, headers=fake_headers))
    if 'res' in json_data:
        if json_data['res'] == False:
            raise ValueError('Server reported id %s is invalid' % id)
    if 'is_paid' in json_data and json_data['is_paid']:
        if 'is_free' in json_data and not json_data['is_free']:
            raise ValueError('%s is paid item' % id)
    if (not title) and 'title' in json_data:
        title = json_data['title']
#no size data in the json. should it be calculated?
    size = 0
    url = json_data['play_path_64']
    if stream_id:
        if stream_id == '1':
            url = json_data['play_path_32']
        elif stream_id == '0':
            url = json_data['play_path']
    logging.debug('ximalaya_download_by_id: %s' % url)
    ext = 'm4a' 
    urls = [url]
    print('Site:        %s' % site_info)
    print('title:       %s' % title)
    if info_only:
        if stream_id:
            print_stream_info(stream_id)

View on GitHub (pinned to 049548f3f3)

Solutions

  1. Verify the track's paid status on the Ximalaya album page in a browser
  2. Download only the free episodes (skip paid ones in a loop, catching ValueError as ximalaya_download_page does)
  3. Purchase the content / use an entitled account if the extractor supports cookies (add auth headers to the get_content call)
  4. Check whether a free lower-quality version exists under a different track id

Example fix

# before
for id in ids:
    ximalaya_download_by_id(id, output_dir=output_dir, info_only=info_only)

# after
for id in ids:
    try:
        ximalaya_download_by_id(id, output_dir=output_dir, info_only=info_only)
    except ValueError:
        print('skipping %s (paid or invalid)' % id)
Defensive patterns

Strategy: try-catch

Validate before calling

import json

def ximalaya_track_free(track_id, fetch):
    d = json.loads(fetch('http://www.ximalaya.com/tracks/%s.json' % track_id))
    return not (d.get('is_paid') and not d.get('is_free', False))

Try / catch

try:
    ximalaya_download(url, ...)
except ValueError as e:
    if 'paid item' in str(e):
        print('paid track; skip or purchase')
    else:
        raise

Prevention

When it happens

Trigger: Downloading a /sound/<id> for a VIP/paid album track: json_data['is_paid'] is truthy and json_data['is_free'] is false at src/you_get/extractors/ximalaya.py:25-27.

Common situations: Album pages mixing free previews with paid chapters; users assuming playlist download covers everything; trial/first episodes being free while the rest are paid.

Related errors


AI-assisted analysis of soimort/you-get@049548f3f3 (2026-08-15). Data as JSON: /api/errors/c66ebe2485b173c1. Report an issue: GitHub.