{"record":{"id":"c42233b03219287e","repo":"jackwener/OpenCLI","slug":"browser-session-required-for-linkedin-learning-sea","errorCode":null,"errorMessage":"Browser session required for linkedin-learning search","messagePattern":"Browser session required for linkedin-learning search","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin-learning/search.js","lineNumber":64,"sourceCode":"        url: slug ? `https://www.linkedin.com/learning/${slug}` : '',\n    };\n}\n\ncli({\n    site: 'linkedin-learning',\n    name: 'search',\n    access: 'read',\n    description: 'Search LinkedIn Learning courses, videos, and learning paths by keyword',\n    domain: DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    args: [\n        { name: 'keywords', type: 'string', required: true, positional: true, help: 'Search keywords, e.g. \"AI agent\"' },\n        { name: 'limit', type: 'int', default: 10, help: `Maximum results to return (1-${MAX_LIMIT})` },\n    ],\n    columns: ['rank', 'type', 'title', 'instructor', 'difficulty', 'duration_sec', 'rating', 'rating_count', 'viewers', 'url'],\n    func: async (page, args) => {\n        if (!page) throw new CommandExecutionError('Browser session required for linkedin-learning search');\n        const keywords = normalizeWhitespace(args.keywords);\n        if (!keywords) throw new ArgumentError('--keywords is required');\n        const limit = parseLimit(args.limit);\n\n        const url = `https://www.linkedin.com/learning-api/searchV2?keywords=${encodeURIComponent(keywords)}&q=keywords`;\n        const result = await fetchLinkedInLearningApi(page, url);\n        if (!result?.json) {\n            throw new CommandExecutionError(`LinkedIn Learning searchV2 failed: ${result?.error ?? 'no payload'}`);\n        }\n        const elements = result.json?.elements;\n        if (!Array.isArray(elements)) {\n            throw new CommandExecutionError('LinkedIn Learning searchV2 returned malformed payload: missing elements array');\n        }\n        if (elements.length === 0) {\n            throw new EmptyResultError(`No LinkedIn Learning results for \"${keywords}\"`);\n        }\n        const rows = [];\n        for (const el of elements) {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin-learning/search.js#L46-L82","documentation":"The linkedin-learning search command requires an authenticated browser session (browser: true, COOKIE strategy) to call the learning-api searchV2 endpoint with the user's LinkedIn cookies. If func is invoked with page === null, meaning no browser session exists, this CommandExecutionError is thrown immediately, before keyword validation or any network activity.","triggerScenarios":"Invoking the search command through a code path that doesn't launch a browser (direct func call, harness passing null, browser startup disabled/failed) so func's page parameter is null.","commonSituations":"Playwright browsers not installed in a fresh CI container; running in an environment that forbids browser launch; bypassing the CLI bootstrap when calling the command function programmatically.","solutions":["Run the command through the normal CLI entry point so the Playwright page is provisioned and passed in.","Install/repair Playwright browser binaries (npx playwright install) so session bootstrap succeeds.","Confirm you are logged in to linkedin.com in the session, since search relies on shared cookies."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!browserPage) {\n  throw new Error('linkedin-learning search requires a browser session; launch one first');\n}","typeGuard":"function hasBrowserPage(p) { return p !== null && p !== undefined && typeof p.goto === 'function'; }","tryCatchPattern":"try {\n  await runCommand('linkedin-learning', 'search', [keywords]);\n} catch (e) {\n  if (String(e.message).includes('Browser session required')) {\n    await launchBrowserAndLogin(); // then retry\n  } else throw e;\n}","preventionTips":["Never call the command func directly with a null page; go through the CLI bootstrap.","Ensure Playwright browsers are installed where the command runs (CI images often miss them).","Confirm the LinkedIn cookie session is active before batch searching."],"tags":["browser-session","prerequisite","linkedin-learning"],"backgroundTag":"missing-browser-session","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}