ytdl-org/youtube-dl · error · ExtractorError

%s said: %s

Error message

%s said: %s

What it means

Raised by PluralsightBaseIE._download_course when the GraphQL bootstrapPlayer response lacks data.rpc.bootstrapPlayer.course. The message is '<IE_NAME> said: <response.error.message>' — the GraphQL server's error, e.g. unauthorized or course not found. Expected=True: the API responded with an error payload.

Source

Thrown at youtube_dl/extractor/pluralsight.py:108

            return self._download_json(
                'https://app.pluralsight.com/player/user/api/v1/player/payload',
                display_id, data=urlencode_postdata({'courseId': course_id}),
                headers={'Referer': url})

    def _download_course_rpc(self, course_id, url, display_id):
        response = self._download_json(
            self._GRAPHQL_EP, display_id, data=json.dumps({
                'query': self._GRAPHQL_COURSE_TMPL % course_id,
                'variables': {}
            }).encode('utf-8'), headers=self._GRAPHQL_HEADERS)

        course = try_get(
            response, lambda x: x['data']['rpc']['bootstrapPlayer']['course'],
            dict)
        if course:
            return course

        raise ExtractorError(
            '%s said: %s' % (self.IE_NAME, response['error']['message']),
            expected=True)


class PluralsightIE(PluralsightBaseIE):
    IE_NAME = 'pluralsight'
    _VALID_URL = r'https?://(?:(?:www|app)\.)?pluralsight\.com/(?:training/)?player\?'
    _LOGIN_URL = 'https://app.pluralsight.com/id/'

    _NETRC_MACHINE = 'pluralsight'

    _TESTS = [{
        'url': 'http://www.pluralsight.com/training/player?author=mike-mckeown&name=hosting-sql-server-windows-azure-iaas-m7-mgmt&mode=live&clip=3&course=hosting-sql-server-windows-azure-iaas',
        'md5': '4d458cf5cf4c593788672419a8dd4cf8',
        'info_dict': {
            'id': 'hosting-sql-server-windows-azure-iaas-m7-mgmt-04',
            'ext': 'mp4',
            'title': 'Demo Monitoring',

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Authenticate first (netrc/cookies with a valid Pluralsight subscription)
  2. Confirm the course id in the URL is real by opening it at pluralsight.com
  3. Update yt-dlp — Pluralsight's GraphQL schema changes are fixed there periodically
Defensive patterns

Strategy: try-catch

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if e.expected and 'Pluralsight said:' in str(e):
        # GraphQL error text: unauthorized → fix session; not found → fix URL
        handle(str(e))

Prevention

When it happens

Trigger: POST to the GraphQL endpoint with the course query where Pluralsight returns an 'error' object: unauthenticated access to paid courses, invalid course id, or the rpc/bootstrapPlayer field renamed (then 'message' itself may KeyError).

Common situations: Extracting paid courses without valid login; expired session token from --cookies; Pluralsight moving to a different player bootstrap API, breaking the query shape.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/5b03497617a4b469. Report an issue: GitHub.