jackwener/OpenCLI · error · CommandExecutionError
LinkedIn jobs preferences returned malformed alerts payload
Error message
LinkedIn jobs preferences returned malformed alerts payload
What it means
Thrown by normalizePreferences when the alerts payload (extracted from LinkedIn's job alerts page) is not a non-null object. Like the preferences guard, it rejects malformed scrape results before reading raw_preferences. The second page navigation (ALERTS_URL) returned something other than the expected object.
Source
Thrown at clis/linkedin/jobs-preferences.js:68
const line = lines[i];
if (/alert/i.test(line) && line.length < 160) {
alerts.push([line, lines[i + 1], lines[i + 2]].filter(Boolean).join(' | '));
}
}
return {
alerts_url: location.href,
job_alerts: Array.from(new Set(alerts)).slice(0, 20),
raw_preferences: clean(text).slice(0, 3000),
};
})()`;
}
function normalizePreferences(preferences, alerts) {
if (!preferences || typeof preferences !== 'object') {
throw new CommandExecutionError('LinkedIn jobs preferences returned malformed preferences payload');
}
if (!alerts || typeof alerts !== 'object') {
throw new CommandExecutionError('LinkedIn jobs preferences returned malformed alerts payload');
}
const preferenceText = normalizeWhitespace(preferences.raw_preferences);
const alertText = normalizeWhitespace(alerts.raw_preferences);
if (!preferenceText && !alertText) {
throw new CommandExecutionError('LinkedIn jobs preferences could not find stable preferences content');
}
return {
open_to_work: inferOpenToWork(`${preferenceText} ${alertText}`),
job_titles: Array.isArray(preferences.job_titles) ? preferences.job_titles.map(normalizeWhitespace).filter(Boolean).join('; ') : '',
locations: Array.isArray(preferences.locations) ? preferences.locations.map(normalizeWhitespace).filter(Boolean).join('; ') : '',
job_alerts: Array.isArray(alerts.job_alerts) ? alerts.job_alerts.map(normalizeWhitespace).filter(Boolean).join('; ') : '',
preferences_url: normalizeWhitespace(preferences.preferences_url),
alerts_url: normalizeWhitespace(alerts.alerts_url),
raw_preferences: preferenceText.slice(0, 1200),
};
}
cli({View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the session stayed authenticated through the second page.goto(ALERTS_URL)
- Increase wait time after navigating to ALERTS_URL
- Create/save at least one job alert or update buildAlertsScript() for the empty-state DOM
- Log the raw alerts evaluate result to distinguish empty-state vs authwall vs markup change
Example fix
// before
const alerts = unwrapEvaluateResult(await page.evaluate(buildAlertsScript()));
return out(normalizePreferences(preferences, alerts));
// after
const alerts = unwrapEvaluateResult(await page.evaluate(buildAlertsScript()));
if (!alerts || typeof alerts !== 'object') {
alerts = { raw_preferences: '', job_alerts: [] };
}
return out(normalizePreferences(preferences, alerts)); Defensive patterns
Strategy: type-guard
Validate before calling
const alertData = unwrapEvaluateResult(await page.evaluate(buildAlertsScript()));
if (!alertData || typeof alertData !== 'object' || Array.isArray(alertData)) {
throw new Error('alerts extraction returned non-object — check ALERTS_URL page load/auth');
} Type guard
function isAlertsPayload(v) {
return typeof v === 'object' && v !== null && !Array.isArray(v) && ('raw_preferences' in v || 'job_alerts' in v);
} Try / catch
try {
return normalizePreferences(preferences, alerts);
} catch (err) {
if (String(err.message).includes('malformed alerts payload')) {
await page.goto(ALERTS_URL);
await page.wait(8);
alerts = unwrapEvaluateResult(await page.evaluate(buildAlertsScript()));
} else throw err;
} Prevention
- Re-check authentication before the second navigation — cookies can invalidate mid-run
- Wait adequately after ALERTS_URL navigation before evaluate
- Create at least one job alert on the account to avoid empty-state payloads
- Keep the alerts extraction script updated against LinkedIn DOM changes
When it happens
Trigger: page.evaluate on ALERTS_URL returning null/undefined/primitive because the alerts page didn't load its data (authwall, empty alerts state, DOM change) or unwrapEvaluateResult flattened an unexpected shape.
Common situations: User has never configured job alerts so the alerts page renders no structured payload; redirect to login after cookie expiry mid-run; LinkedIn A/B-tested markup so the extraction script returns null.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- LinkedIn jobs preferences returned malformed preferences pay
- LinkedIn people search returned malformed extraction payload
- LinkedIn people search returned malformed row at index ${ind
- LinkedIn people search returned row without stable profile i
- LinkedIn messengerMessages API returned a malformed page wra
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/08e9a1932438e229.
Report an issue: GitHub.