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
- Verify connectivity: curl -I https://medium.com/feed/tag/programming from the same machine.
- Check proxy/firewall/VPN settings and set HTTPS_PROXY if your network requires one.
- Retry after confirming status.medium.com or Medium itself is not down.
- 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
- Check outbound connectivity to medium.com before running batch jobs.
- Configure HTTPS_PROXY in restricted/corporate networks.
- Add exponential backoff around network-dependent CLI calls.
- Monitor Medium's status page for outages before blaming local config.
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
- `${label} returned malformed JSON: ${err?.message ?? err}`
- ${label} request failed: ${outcome.detail}
- linux.do request failed: HTTP ${result.status ?? 'unknown'}
- mdn search request failed: ${err?.message ?? err}
- medium tag returned HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/17235ff861fe00e2.
Report an issue: GitHub.