jackwener/OpenCLI · error · ArgumentError

Invalid LinkedIn Learning host: "${parsed.hostname}"

Error message

Invalid LinkedIn Learning host: "${parsed.hostname}"

What it means

Thrown by parseSlug when the user passes a full http(s) URL whose hostname is not linkedin.com or www.linkedin.com. The library only accepts course URLs on official LinkedIn hosts, so any other domain (typos, shortener redirects, mirror sites) is rejected before any network call. It is an ArgumentError, i.e. a caller-input validation failure.

Source

Thrown at clis/linkedin-learning/course.js:21

 */
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
import { DOMAIN, fetchLinkedInLearningApi, normalizeWhitespace } from './shared.js';

function parseSlug(value) {
    const s = normalizeWhitespace(value);
    if (!s) throw new ArgumentError('<slug> is required');
    let slug = s;
    if (/^https?:\/\//i.test(s)) {
        let parsed;
        try {
            parsed = new URL(s);
        } catch {
            throw new ArgumentError(`Invalid LinkedIn Learning URL: "${s}"`);
        }
        const host = parsed.hostname.toLowerCase();
        if (host !== 'linkedin.com' && host !== 'www.linkedin.com') {
            throw new ArgumentError(`Invalid LinkedIn Learning host: "${parsed.hostname}"`);
        }
        const m = parsed.pathname.match(/^\/learning\/([^/?#]+)/);
        if (!m) throw new ArgumentError(`Invalid LinkedIn Learning course URL: "${s}"`);
        slug = m[1];
    } else {
        const m = s.match(/^\/?learning\/([^/?#]+)/);
        slug = m ? m[1] : s;
    }
    if (!/^[a-zA-Z0-9-_]+$/.test(slug)) {
        throw new ArgumentError(`Invalid LinkedIn Learning slug: "${slug}"`);
    }
    return slug;
}

function parseCourse(el, slug) {
    const title = normalizeWhitespace(el?.title);
    if (!title) return null;
    const description = typeof el?.description === 'string'

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass the plain course slug (e.g. 'agentic-ai-build-your-first-agentic-ai-system') instead of a URL.
  2. Use a URL on www.linkedin.com, e.g. https://www.linkedin.com/learning/<slug>/, or the path form '/learning/<slug>'.
  3. Resolve any URL shortener to its final linkedin.com destination before passing it.

Example fix

// before
opencli linkedin-learning course 'https://lnkd.in/learning/agentic-ai-basics'
// after
opencli linkedin-learning course 'https://www.linkedin.com/learning/agentic-ai-basics/'
Defensive patterns

Strategy: validation

Validate before calling

function isLinkedInHost(u) {
  try {
    const { hostname } = new URL(u);
    const h = hostname.toLowerCase();
    return h === 'linkedin.com' || h === 'www.linkedin.com';
  } catch { return false; }
}
// call: if (arg.startsWith('http') && !isLinkedInHost(arg)) fixBeforeCalling(arg);

Type guard

function isLinkedInLearningUrl(v) {
  try {
    const u = new URL(v);
    const h = u.hostname.toLowerCase();
    return (h === 'linkedin.com' || h === 'www.linkedin.com') && /^\/learning\/[^/?#]+/.test(u.pathname);
  } catch { return false; }
}

Try / catch

try {
  run(['linkedin-learning', 'course', arg]);
} catch (e) {
  if (String(e.message).includes('Invalid LinkedIn Learning host')) {
    // strip to slug or resolve shortener, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the linkedin-learning course command with args.slug set to an http(s) URL whose parsed hostname is not exactly 'linkedin.com' or 'www.linkedin.com' (case-insensitive), e.g. 'https://linkedin.elearning.example/learning/foo' or 'https://lnkd.in/learning/foo'.

Common situations: Passing a link copied from a LinkedIn learning-path partner site, a URL shortener (lnkd.in), a staging/corporate proxy host, or a regional mirror; typo like 'linkedi n.com'; pasting a LinkedIn post URL instead of a course URL after editing the domain.

Related errors


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