ytdl-org/youtube-dl · error · ExtractorError

%s said: %s

Error message

%s said: %s

What it means

Raised by NexxIE._handle_error when an api.nexx.cloud v3 response carries metadata.status outside 200-299. The message forwards the API's own metadata.errorhint verbatim (prefixed by the IE name). It is expected=True, so it maps a clean API-level failure to an ExtractorError.

Source

Thrown at youtube_dl/extractor/nexx.py:145

                    webpage):
                entries.append(
                    'https://api.nexx.cloud/v3/%s/videos/byid/%s'
                    % (domain_id, video_id))

        # TODO: support more embed formats

        return entries

    @staticmethod
    def _extract_url(webpage):
        return NexxIE._extract_urls(webpage)[0]

    def _handle_error(self, response):
        status = int_or_none(try_get(
            response, lambda x: x['metadata']['status']) or 200)
        if 200 <= status < 300:
            return
        raise ExtractorError(
            '%s said: %s' % (self.IE_NAME, response['metadata']['errorhint']),
            expected=True)

    def _call_api(self, domain_id, path, video_id, data=None, headers={}):
        headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
        result = self._download_json(
            'https://api.nexx.cloud/v3/%s/%s' % (domain_id, path), video_id,
            'Downloading %s JSON' % path, data=urlencode_postdata(data),
            headers=headers)
        self._handle_error(result)
        return result['result']

    def _extract_free_formats(self, video, video_id):
        stream_data = video['streamdata']
        cdn = stream_data['cdnType']
        assert cdn == 'free'

        hash = video['general']['hash']

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Read the errorhint — it is Nexx's own explanation (unknown domain, missing resource, expired token) and names the actual problem.
  2. Update youtube-dl / yt-dlp; domain-id extraction drift is the usual root cause.
  3. Verify the video still plays on the customer site embedding Nexx; if withdrawn, there is nothing to fetch.

Example fix

pip install -U yt-dlp   # then retry the embedding page URL
Defensive patterns

Strategy: try-catch

Validate before calling

import requests
r = requests.post(f'https://api.nexx.cloud/v3/{domain_id}/{path}', ...).json()
if not 200 <= int(r.get('metadata', {}).get('status') or 200) < 300:
    print('nexx api error:', r['metadata'].get('errorhint'))

Try / catch

except ExtractorError as e:
    if e.expected and str(e).startswith('Nexx said:'):
        hint = str(e).split('said:', 1)[1]
        if 'domain' in hint.lower():
            report_upstream(url)  # domain_id extraction failed
        else:
            mark_unavailable(url, hint)
    else:
        raise

Prevention

When it happens

Trigger: Any _call_api POST/GET to https://api.nexx.cloud/v3/<domain_id>/<path> whose JSON has metadata.status >= 300 or < 200; the errorhint string is surfaced to the user.

Common situations: Wrong/stale domain_id extracted from the embedding page (API rejects it); videos deleted or unpublished on the Nexx side; API contract changes after the extractor was written.

Related errors


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