jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu/unfollow: malformed ${context} payload
Error message
xiaohongshu/unfollow: malformed ${context} payload What it means
Thrown by requireActionResult() in the xiaohongshu unfollow flow when a browser page.evaluate payload does not have the expected action-result shape. After unwrapEvaluateResult, the value must be a non-null, non-array object with a boolean `ok` field; otherwise the click/confirm step cannot tell success from failure and the command aborts with this malformed-payload error.
Source
Thrown at clis/xiaohongshu/unfollow.js:31
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, AuthRequiredError, CliError, CommandExecutionError } from '@jackwener/opencli/errors';
import { normalizeXhsUserId } from './user-helpers.js';
import { unwrapEvaluateResult } from './shared.js';
const PROFILE_SETTLE_MS = 2500;
const MODAL_SETTLE_MS = 1500;
const STATE_FLIP_TIMEOUT_MS = 5000;
const USER_ID_RE = /^[a-zA-Z0-9]{8,32}$/;
function isXiaohongshuHost(hostname) {
const host = String(hostname || '').toLowerCase();
return host === 'xiaohongshu.com' || host.endsWith('.xiaohongshu.com');
}
function requireActionResult(payload, context) {
const inner = unwrapEvaluateResult(payload);
if (!inner || typeof inner !== 'object' || Array.isArray(inner) || typeof inner.ok !== 'boolean') {
throw new CommandExecutionError(`xiaohongshu/unfollow: malformed ${context} payload`);
}
return inner;
}
function assertUserId(raw) {
const input = String(raw ?? '').trim();
if (/^https?:\/\//i.test(input)) {
let parsed;
try {
parsed = new URL(input);
} catch {
throw new ArgumentError('xiaohongshu/unfollow: invalid profile URL');
}
if (parsed.protocol !== 'https:' || !isXiaohongshuHost(parsed.hostname)) {
throw new ArgumentError('xiaohongshu/unfollow: profile URL must be an exact https://*.xiaohongshu.com URL');
}
const match = parsed.pathname.match(/^\/user\/profile\/([a-zA-Z0-9]{8,32})\/?$/);
if (!match) {View on GitHub (pinned to 49907e53dc)
Solutions
- Log into Xiaohongshu in the target browser session and confirm the unfollow button/dialog works manually.
- Retry the unfollow — a transient script failure can yield an undefined payload.
- Update the library if the site changed its unfollow UI, since requireActionResult's expected payload shape no longer matches what the injected script returns.
- Inspect the injected evaluate script for the given context ('click result'/'confirm result') and add logging to see the raw payload before this guard throws.
- Ensure you are hitting real xiaohongshu.com pages (host check passes) and not an interstitial/verify page.
Example fix
// before
const res = await page.evaluate(clickScript);
// after
const res = await page.evaluate(clickScript);
if (!res || typeof res !== 'object' || Array.isArray(res) || typeof res.ok !== 'boolean') {
console.error('raw payload:', JSON.stringify(res));
throw new Error(`unexpected unfollow payload: ${JSON.stringify(res)}`);
} Defensive patterns
Strategy: validation
Validate before calling
function isValidActionResult(p) {
return !!p && typeof p === 'object' && !Array.isArray(p) && typeof p.ok === 'boolean';
} Type guard
function isActionResult(payload) {
const inner = unwrapEvaluateResult(payload);
return typeof inner === 'object' && inner !== null && !Array.isArray(inner) && typeof inner.ok === 'boolean';
} Try / catch
try {
await unfollow(userId);
} catch (err) {
if (String(err.message).includes('malformed') && String(err.message).includes('unfollow')) {
await reloginIfNeeded();
return retryUnfollow(userId);
}
throw err;
} Prevention
- Validate evaluate payloads at call sites before relying on `ok`
- Keep the CLI updated with site DOM/endpoint changes
- Ensure an active logged-in session and real xiaohongshu.com pages
- Log raw payloads to detect shape drift early
When it happens
Trigger: clickResult() or confirmResult() evaluates an in-page script whose return value is undefined/null, an array, a non-object, or an object lacking `ok: boolean` — typically because the injected script threw, returned nothing, or the site's DOM/endpoint changed and the script fell through a different path.
Common situations: Xiaohongshu changed the unfollow dialog/endpoint so the injected script's branch never sets `ok`; the evaluate wrapper serialization swallowed an exception and returned undefined; running against a logged-out or risk-control page where the button handler never executes; version drift between the CLI and the site.
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
- Xianyu inbox returned malformed conversation list
- Codex extract-diff returned an invalid payload.
- LinkedIn sent invitations returned a malformed extraction pa
- LinkedIn messengerMessages payload contains a malformed incl
- Manus credits returned a malformed API payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/fd14c5fee393c343.
Report an issue: GitHub.