jackwener/OpenCLI · error · CommandExecutionError

medium tag request failed: ${err?.message ?? err}

Error message

medium tag request failed: ${err?.message ?? err}

What it means

When the HTTP request to Medium's tag RSS feed throws (DNS failure, connection refused, timeout, TLS error), the adapter wraps the underlying message in CommandExecutionError prefixed 'medium tag request failed:'. It distinguishes network-level failure from HTTP status errors handled afterwards.

Source

Thrown at clis/medium/tag.js:104

        { name: 'tag', positional: true, required: true, help: 'Lowercase tag slug (e.g. "programming", "machine-learning")' },
        { name: 'limit', type: 'int', default: 20, help: 'Max articles (1-25 — single RSS page)' },
    ],
    columns: ['rank', 'title', 'author', 'description', 'categories', 'published', 'url'],
    func: async (args) => {
        const tag = requireTag(args.tag);
        const limit = requireBoundedInt(args.limit, 20, 25);
        const url = `https://medium.com/feed/tag/${tag}`;
        let resp;
        try {
            resp = await fetch(url, {
                headers: {
                    'user-agent': 'opencli-medium-adapter (+https://github.com/jackwener/opencli)',
                    accept: 'application/rss+xml, application/xml',
                },
            });
        }
        catch (err) {
            throw new CommandExecutionError(
                `medium tag request failed: ${err?.message ?? err}`,
                'Check that medium.com is reachable from this network.',
            );
        }
        if (resp.status === 404) {
            throw new EmptyResultError('medium tag', `Medium tag "${tag}" does not exist.`);
        }
        if (!resp.ok) {
            throw new CommandExecutionError(`medium tag returned HTTP ${resp.status}`);
        }
        const xml = await resp.text();
        const items = [];
        const re = /<item[^>]*>([\s\S]*?)<\/item>/g;
        let m;
        while ((m = re.exec(xml)) !== null) {
            items.push(m[1]);
        }
        if (!items.length) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify connectivity: curl -I https://medium.com/feed/tag/programming from the same machine.
  2. Check proxy/firewall/VPN settings and set HTTPS_PROXY if your network requires one.
  3. Retry after confirming status.medium.com or Medium itself is not down.
  4. Run with the underlying err.message from the error text to pinpoint DNS vs TLS vs timeout and fix accordingly.

Example fix

// before (blocked network)
medium tag programming   # -> medium tag request failed: getaddrinfo ENOTFOUND medium.com
// after (configure proxy)
export HTTPS_PROXY=http://proxy.corp.local:8080
medium tag programming
Defensive patterns

Strategy: retry

Validate before calling

// preflight: abort early if medium.com is unreachable
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 5000);
try {
  await fetch('https://medium.com/feed/tag/programming', { signal: ctrl.signal });
} finally { clearTimeout(t); }

Try / catch

try {
  await run(['medium', 'tag', tag]);
} catch (e) {
  if (/medium tag request failed:/.test(e.message)) {
    console.error('Network issue reaching medium.com; check DNS/proxy/VPN');
    await sleep(2000); // then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `medium tag <tag>` while offline, behind a proxy/firewall blocking medium.com, with DNS misconfiguration, or when Medium is unreachable/down so fetch itself rejects.

Common situations: Corporate networks blocking medium.com; VPN interference; Docker containers without outbound internet; typo'd DNS or IPv6 issues; Medium outages.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/17235ff861fe00e2. Report an issue: GitHub.