{"record":{"id":"09f3c3f28087bbd8","repo":"jackwener/OpenCLI","slug":"linkedin-salesnav-search","errorCode":null,"errorMessage":"linkedin salesnav-search","messagePattern":"linkedin salesnav-search","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/linkedin/salesnav-search.js","lineNumber":168,"sourceCode":"\n    const leads = [];\n    const seen = new Set();\n    for (let start = 0; leads.length < limit && start < 2000; start += PAGE_SIZE) {\n      const result = unwrapEvaluateResult(await page.evaluate(fetchLeadSearchScript(leadSearchUrl(keywords, start), csrf)));\n      const json = requireLeadSearchResult(result);\n      const pageLeads = parseLeads(json);\n      if (pageLeads.length === 0) break;\n      for (const lead of pageLeads) {\n        const key = lead.profile_url || lead.name.toLowerCase();\n        if (seen.has(key)) continue;\n        seen.add(key);\n        leads.push(lead);\n      }\n      await page.wait(1);\n    }\n\n    if (leads.length === 0) {\n      throw new EmptyResultError('linkedin salesnav-search', 'No Sales Navigator leads were found.');\n    }\n    return leads.slice(0, limit).map((lead, index) => ({ rank: index + 1, ...lead }));\n  },\n});\n\nexport const __test__ = {\n  normalizeWhitespace,\n  parseLimit,\n  leadSearchUrl,\n  profileUrlFromEntityUrn,\n  leadUrlFromEntityUrn,\n  parseLeads,\n  requireLeadSearchResult,\n};\n","sourceCodeStart":150,"sourceCodeEnd":183,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/salesnav-search.js#L150-L183","documentation":"An EmptyResultError raised in clis/linkedin/salesnav-search.js:168 when the pagination loop completed and deduplicated leads but collected zero results. The command treats an empty result set as an exceptional outcome so callers and pipeline steps can detect 'nothing matched' distinctly from malformed responses. The first argument is the command name and the second is the human-readable explanation.","triggerScenarios":"The keyword query matches no Sales Navigator leads; every paginated parseLeads(json) call returned an empty elements array so the loop broke immediately; search results exist but all rows fail entityUrn/name validation and are never pushed (parseLeads would throw first, so practically this is a genuine empty response).","commonSituations":"Overly narrow keyword strings with typos; searching for people outside the account's Sales Navigator visibility (network/degree filters); region-restricted searches returning zero for the signed-in seat; keywords targeting a company with no Sales Navigator-indexed employees.","solutions":["Broaden the keywords (fewer, more generic terms) and re-run, e.g. 'quality manager food' instead of an exact long phrase.","Confirm the account actually has Sales Navigator access and can see results by running the same search in the Sales Navigator UI.","Wrap the call in a try/catch for EmptyResultError when zero results is an acceptable outcome in your pipeline.","Try the query with alternate spellings or via LinkedIn people search if the target population is very small."],"exampleFix":"// before (crash pipeline on empty)\nconst leads = await run('linkedin salesnav-search', ['quality manager food manufacturing']);\n// after (tolerate empty)\ntry {\n  const leads = await run('linkedin salesnav-search', ['quality manager food manufacturing']);\n} catch (err) {\n  if (err.name === 'EmptyResultError') return [];\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"// Sanity-check keywords before the search:\nconst kw = String(keywords || '').trim();\nif (kw.length < 3) throw new Error('keywords too narrow/short for a meaningful Sales Navigator search');","typeGuard":null,"tryCatchPattern":"try {\n  const leads = await run('linkedin salesnav-search', [keywords, '--limit', '50']);\n} catch (err) {\n  if (err.name === 'EmptyResultError') {\n    console.warn(`No leads for \"${keywords}\"; broadening query.`);\n    return run('linkedin salesnav-search', [keywords.split(/\\s+/).slice(0, 2).join(' ')]);\n  }\n  throw err;\n}","preventionTips":["Start with broad keywords and narrow iteratively; long exact phrases often match nothing.","Confirm the signed-in seat can see the target population in the Sales Navigator UI before automating.","Treat EmptyResultError as data (catch and return []) when zero hits is a valid business outcome."],"tags":["linkedin","sales-navigator","empty-result","search"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}