{"record":{"id":"74fd9ec2f2532729","repo":"jackwener/OpenCLI","slug":"sales-navigator-profile-lookup-returned-malformed","errorCode":null,"errorMessage":"Sales Navigator profile lookup returned malformed profile data","messagePattern":"Sales Navigator profile lookup returned malformed profile data","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/salesnav-message.js","lineNumber":245,"sourceCode":"}\n\nfunction profileSummary(json) {\n  const data = json?.data || json || {};\n  const pos = data.defaultPosition || (Array.isArray(data.positions) ? data.positions.find((p) => p.current) || data.positions[0] : {}) || {};\n  return {\n    recipient: normalizeWhitespace(data.fullName || [data.firstName, data.lastName].filter(Boolean).join(' ')),\n    title: normalizeWhitespace(pos.title || data.headline || ''),\n    company: normalizeWhitespace(pos.companyName || pos.company?.name || ''),\n    degree: normalizeWhitespace(data.degree || ''),\n    inmail_restriction: normalizeWhitespace(data.inmailRestriction || ''),\n    open_link: Boolean(data.memberBadges?.openLink),\n  };\n}\n\nfunction requireProfileSummary(json) {\n  const summary = profileSummary(json);\n  if (!summary.recipient) {\n    throw new CommandExecutionError('Sales Navigator profile lookup returned malformed profile data', 'missing_recipient_name');\n  }\n  return summary;\n}\n\ncli({\n  site: 'linkedin',\n  name: 'salesnav-message',\n  access: 'write',\n  description: 'Send or dry-run a LinkedIn Sales Navigator InMail to a lead using the Sales Navigator messaging API',\n  domain: LINKEDIN_DOMAIN,\n  strategy: Strategy.UI,\n  browser: true,\n  args: [\n    { name: 'recipient', type: 'string', required: true, positional: true, help: 'Sales Navigator lead URL, LinkedIn /in/ URL from salesnav-search, or urn:li:fs_salesProfile:(...)' },\n    { name: 'subject', type: 'string', required: true, help: 'InMail subject' },\n    { name: 'body', type: 'string', required: true, help: 'InMail body' },\n    { name: 'send', type: 'bool', default: false, help: 'Actually send the InMail. Default is dry-run validation only.' },\n    { name: 'copy-to-crm', type: 'bool', default: false, help: 'Set Sales Navigator copyToCrm on the message request' },","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/salesnav-message.js#L227-L263","documentation":"requireProfileSummary extracts a summary from the salesApiProfiles JSON and requires a recipient name. If profileSummary yields no recipient field (missing/empty name in the API response), it throws CommandExecutionError with detail 'missing_recipient_name'.","triggerScenarios":"profileResult returns JSON whose data.defaultPosition/positions shape parses but the recipient (full name) is absent — e.g. the profile API returned a stub object, an empty data payload, or a restricted profile.","commonSituations":"LinkedIn returning degraded/partial profile data; the recipient's profile was removed or restricted; Sales Nav API shape change renaming name fields; probing the wrong id after a failed resolution.","solutions":["Dump the raw profile JSON and check the data.defaultPosition/positions and name fields","Re-resolve the recipient (see error 2376) to ensure the profileId/authToken are correct","Verify the profile is still viewable in Sales Navigator","Update profileSummary parsing if LinkedIn changed the field layout"],"exampleFix":"null","handlingStrategy":"validation","validationCode":"const data = json?.data || json || {};\nconst name = data?.fullName || data?.name || data?.recipient;\nif (!name) throw new Error('Profile JSON has no recipient name — check the raw payload');","typeGuard":"const hasRecipientName = (json) => {\n  const d = json?.data ?? json ?? {};\n  return typeof (d.fullName || d.name || d.recipient) === 'string' && (d.fullName || d.name || d.recipient).length > 0;\n};","tryCatchPattern":"try {\n  const summary = requireProfileSummary(json);\n} catch (err) {\n  if (err?.detail === 'missing_recipient_name') {\n    console.warn('Degraded profile data; dump json for inspection');\n  } else throw err;\n}","preventionTips":["Log the raw profile JSON on failure to spot schema drift","Re-resolve the recipient if profileId/authToken may be stale","Confirm the profile is still visible in Sales Navigator","Keep parsing code updated with LinkedIn's field names"],"tags":["linkedin","sales-navigator","missing-data","profile"],"backgroundTag":"malformed-api-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}