jackwener/OpenCLI · error · CommandExecutionError

Sales Navigator profile lookup returned malformed profile da

Error message

Sales Navigator profile lookup returned malformed profile data

What it means

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'.

Source

Thrown at clis/linkedin/salesnav-message.js:245

}

function profileSummary(json) {
  const data = json?.data || json || {};
  const pos = data.defaultPosition || (Array.isArray(data.positions) ? data.positions.find((p) => p.current) || data.positions[0] : {}) || {};
  return {
    recipient: normalizeWhitespace(data.fullName || [data.firstName, data.lastName].filter(Boolean).join(' ')),
    title: normalizeWhitespace(pos.title || data.headline || ''),
    company: normalizeWhitespace(pos.companyName || pos.company?.name || ''),
    degree: normalizeWhitespace(data.degree || ''),
    inmail_restriction: normalizeWhitespace(data.inmailRestriction || ''),
    open_link: Boolean(data.memberBadges?.openLink),
  };
}

function requireProfileSummary(json) {
  const summary = profileSummary(json);
  if (!summary.recipient) {
    throw new CommandExecutionError('Sales Navigator profile lookup returned malformed profile data', 'missing_recipient_name');
  }
  return summary;
}

cli({
  site: 'linkedin',
  name: 'salesnav-message',
  access: 'write',
  description: 'Send or dry-run a LinkedIn Sales Navigator InMail to a lead using the Sales Navigator messaging API',
  domain: LINKEDIN_DOMAIN,
  strategy: Strategy.UI,
  browser: true,
  args: [
    { name: 'recipient', type: 'string', required: true, positional: true, help: 'Sales Navigator lead URL, LinkedIn /in/ URL from salesnav-search, or urn:li:fs_salesProfile:(...)' },
    { name: 'subject', type: 'string', required: true, help: 'InMail subject' },
    { name: 'body', type: 'string', required: true, help: 'InMail body' },
    { name: 'send', type: 'bool', default: false, help: 'Actually send the InMail. Default is dry-run validation only.' },
    { name: 'copy-to-crm', type: 'bool', default: false, help: 'Set Sales Navigator copyToCrm on the message request' },

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Dump the raw profile JSON and check the data.defaultPosition/positions and name fields
  2. Re-resolve the recipient (see error 2376) to ensure the profileId/authToken are correct
  3. Verify the profile is still viewable in Sales Navigator
  4. Update profileSummary parsing if LinkedIn changed the field layout

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

const data = json?.data || json || {};
const name = data?.fullName || data?.name || data?.recipient;
if (!name) throw new Error('Profile JSON has no recipient name — check the raw payload');

Type guard

const hasRecipientName = (json) => {
  const d = json?.data ?? json ?? {};
  return typeof (d.fullName || d.name || d.recipient) === 'string' && (d.fullName || d.name || d.recipient).length > 0;
};

Try / catch

try {
  const summary = requireProfileSummary(json);
} catch (err) {
  if (err?.detail === 'missing_recipient_name') {
    console.warn('Degraded profile data; dump json for inspection');
  } else throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


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