jackwener/OpenCLI · warning · CommandExecutionError
LinkedIn company extraction returned a malformed followers c
Error message
LinkedIn company extraction returned a malformed followers count
What it means
normalizeCompanyInfo parses a company name/followers blob from the LinkedIn company page and coerces every field to plain strings/numbers. If the page reports a followers count but it cannot be coerced to a finite number (e.g. '1,200+ employees' markup drift or localized text), it throws to prevent propagating a NaN followers value to callers.
Source
Thrown at clis/linkedin/company.js:112
slug = decodeURIComponent(match[1]);
} catch {
throw new CommandExecutionError('LinkedIn company extraction returned a malformed company slug');
}
return `https://${LINKEDIN_DOMAIN}/company/${encodeURIComponent(slug)}/about/`;
}
function normalizeCompanyInfo(info, targetUrl) {
if (!info || typeof info !== 'object' || Array.isArray(info)) {
throw new CommandExecutionError('LinkedIn company extraction returned a malformed payload');
}
if (!info.name) {
throw new CommandExecutionError('LinkedIn company page rendered but no company name was found (layout drift or company not found)');
}
let followers = 0;
if (info.followers) {
followers = Number(info.followers);
if (!Number.isFinite(followers)) {
throw new CommandExecutionError('LinkedIn company extraction returned a malformed followers count');
}
}
return {
name: String(info.name),
industry: String(info.industry || ''),
size: String(info.size || ''),
headquarters: String(info.headquarters || ''),
founded: String(info.founded || ''),
website: String(info.website || ''),
specialties: String(info.specialties || ''),
followers,
about: String(info.about || ''),
url: normalizeCompanyOutputUrl(info.url, targetUrl),
};
}
cli({
site: 'linkedin',View on GitHub (pinned to 49907e53dc)
Solutions
- Log the raw info.followers value scraped from the page and extend/fix the extraction regex or selector to capture only digits
- Pre-sanitize the string: strip commas, '+', 'followers', and expand K/M suffixes before calling Number()
- Fall back to 0 followers (or omit the field) instead of throwing if the count is non-essential
- Re-run the command; if persistent, check for library updates addressing LinkedIn layout drift
Example fix
// before
followers = Number(info.followers);
if (!Number.isFinite(followers)) {
throw new CommandExecutionError('LinkedIn company extraction returned a malformed followers count');
}
// after
const raw = String(info.followers).replace(/[,+\s]|followers/gi, '');
const mult = /k$/i.test(raw) ? 1e3 : /m$/i.test(raw) ? 1e6 : 1;
followers = Number.parseFloat(raw) * mult;
if (!Number.isFinite(followers)) followers = 0; Defensive patterns
Strategy: validation
Validate before calling
function isValidFollowers(raw) { if (raw == null || raw === '') return true; const n = Number(String(raw).replace(/[,+\s]|followers/gi, '')); return Number.isFinite(n); }
// call before invoking: if (!isValidFollowers(rawFollowersText)) { /* sanitize or skip */ } Type guard
function isFiniteCount(v) { return typeof v === 'number' ? Number.isFinite(v) : v == null || v === '' ? true : Number.isFinite(Number(String(v).replace(/[^0-9.km]/gi, ''))); } Try / catch
try { const company = await getCompany(url); } catch (e) { if (String(e.message).includes('malformed followers count')) { company.followers = 0; } else { throw e; } } Prevention
- Sanitize scraped follower text (strip commas, '+', 'followers', expand K/M) before it reaches the library
- Pin and update the library when LinkedIn changes markup
- Treat followers as optional data and default to 0 in your consumers
- Log raw scraped values in staging to catch extraction drift early
When it happens
Trigger: Calling the LinkedIn company command when info.followers is truthy but Number(info.followers) yields NaN/Infinity — e.g. LinkedIn markup changed and the raw scraped followers string now contains 'followers', 'K'/'M' suffixes, or locale-specific separators.
Common situations: LinkedIn layout/attribute drift breaking the selector that captures the followers text; localized pages ('1.2M followers' in another language); the scraping regex grabbing surrounding decorative text.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Barchart greeks returned an unreadable options payload${data
- PARSE_ERROR
- ${command} parser returned an unexpected shape
- No rows were found in the visible HLTV page
- ${command} parser returned row ${index + 1} without required
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/494bc12dedb3caf5.
Report an issue: GitHub.