{"record":{"id":"f82c503d442bfc7a","repo":"jackwener/OpenCLI","slug":"keywords-is-required","errorCode":null,"errorMessage":"--keywords is required","messagePattern":"--keywords is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/linkedin-learning/search.js","lineNumber":66,"sourceCode":"}\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) {\n            if (rows.length >= limit) break;\n            const row = parseRow(el, rows.length + 1);","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin-learning/search.js#L48-L84","documentation":"After normalizing whitespace, the keywords argument is empty, so the search would be meaningless; the library throws this ArgumentError before issuing the API call. Note that args.keywords is declared required, but a whitespace-only string can still pass the CLI layer and be caught here.","triggerScenarios":"Calling linkedin-learning search with keywords = '' or '   ' (whitespace only), or invoking the command programmatically with args.keywords undefined/null so normalizeWhitespace yields an empty string.","commonSituations":"Shell quoting bugs that drop the quoted argument ('\"\"'); a script variable that is empty/unset; passing an option value into the wrong positional slot; upstream data producing blank search terms.","solutions":["Provide non-empty keywords, e.g. opencli linkedin-learning search 'AI agent'.","Check shell quoting/variable expansion — an empty \"$VAR\" collapses to nothing; guard before invoking.","In scripts, validate the search term is non-blank before calling the command."],"exampleFix":"// before\nKEYWORDS=\"\"\nopencli linkedin-learning search \"$KEYWORDS\"\n// after\nKEYWORDS=\"AI agent\"\n[ -n \"$KEYWORDS\" ] && opencli linkedin-learning search \"$KEYWORDS\"","handlingStrategy":"validation","validationCode":"const kw = (keywords ?? '').trim();\nif (!kw) {\n  throw new Error('keywords must be a non-empty string before calling linkedin-learning search');\n}","typeGuard":"function hasKeywords(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  await runCommand('linkedin-learning', 'search', [keywords]);\n} catch (e) {\n  if (e.message.includes('--keywords is required')) {\n    // fix upstream quoting/empty variable, then retry with a real term\n  } else throw e;\n}","preventionTips":["Quote positional args in shell: search \"AI agent\" — unquoted multi-word input breaks parsing.","Guard script variables for emptiness before invoking (${VAR:?} in bash).","Trim/normalize user-supplied search terms at the boundary of your integration."],"tags":["argument-validation","empty-input","linkedin-learning"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}