jackwener/OpenCLI · error · CommandExecutionError
Jike search API returned a malformed post
Error message
Jike search API returned a malformed post
What it means
mapPost validates each search result item from the Jike /1.0/search/integrate API before mapping it to an output row. It throws CommandExecutionError when an item is not an object or lacks a non-empty string id, because every row needs a stable id and post URL. This guards against Jike returning unexpected result shapes inside body.data.
Source
Thrown at clis/jike/search.js:25
const DEFAULT_LIMIT = 20;
const MAX_PAGES = 50;
async function fetchSearchPage(page, keyword, loadMoreKey) {
const requestBody = {
keywords: keyword,
limit: PAGE_SIZE,
...(loadMoreKey ? { loadMoreKey } : {}),
};
const body = await postJikeApi(page, API_PATH, requestBody, 'Jike search API');
if (!body || typeof body !== 'object' || body.success !== true || !Array.isArray(body.data)) {
throw new CommandExecutionError(`Jike search API failed: ${String(body?.message || 'malformed response')}`);
}
return body;
}
function mapPost(post) {
if (!post || typeof post !== 'object' || typeof post.id !== 'string' || !post.id) {
throw new CommandExecutionError('Jike search API returned a malformed post');
}
const content = typeof post.content === 'string' ? post.content : '';
return {
id: post.id,
author: typeof post.user?.screenName === 'string' ? post.user.screenName : '',
content: content.replace(/\n/g, ' ').slice(0, 120),
likes: Number.isFinite(Number(post.likeCount)) ? Number(post.likeCount) : 0,
comments: Number.isFinite(Number(post.commentCount)) ? Number(post.commentCount) : 0,
time: typeof post.actionTime === 'string' ? post.actionTime : (typeof post.createdAt === 'string' ? post.createdAt : ''),
url: `https://web.okjike.com/originalPost/${post.id}`,
};
}
async function searchPosts(page, keyword, limit) {
const rows = [];
const seenIds = new Set();
const seenCursors = new Set();
let loadMoreKey = null;View on GitHub (pinned to 49907e53dc)
Solutions
- Re-login to Jike in the browser session (cookie strategy) and retry the search — stale sessions often yield degraded responses.
- Reduce --limit and retry to see if a specific post triggers it; if so the post's payload is anomalous.
- Update the CLI/package — the mapping may need adjusting for a Jike API schema change.
- Log the raw failing item (e.g. JSON.stringify) and file an issue so mapPost can be widened or the field fixed.
Example fix
// before
function mapPost(post) {
if (!post || typeof post !== 'object' || typeof post.id !== 'string' || !post.id) {
throw new CommandExecutionError('Jike search API returned a malformed post');
}
...
}
// after: tolerate and skip bad items instead of failing the whole command
function mapPost(post) {
if (!post || typeof post !== 'object' || typeof post.id !== 'string' || !post.id) {
console.error('skipping malformed post:', JSON.stringify(post));
return null;
}
...
} Defensive patterns
Strategy: type-guard
Validate before calling
// validate API items before mapping
function isMappedPost(item) {
return item && typeof item === 'object' && typeof item.id === 'string' && item.id.length > 0;
} Type guard
const isPost = (p) => !!p && typeof p === 'object' && typeof p.id === 'string' && !!p.id;
Try / catch
try {
const rows = await runCli(['jike', 'search', keyword]);
} catch (e) {
if (/malformed post/.test(e.message)) {
console.error('Jike response schema changed; retry or update CLI');
return [];
}
throw e;
} Prevention
- Keep the CLI updated against Jike API schema changes.
- Log raw response items when this error occurs to diagnose the new shape.
- Wrap row mapping so one bad item does not fail the whole command.
- Ensure the browser session is logged in — degraded sessions yield odd payloads.
When it happens
Trigger: A data[] item in the search response is null, a non-object (e.g. a string), or an object whose post.id is missing, not a string, or an empty string. Items with type !== 'ORIGINAL_POST' are skipped before mapPost, so only ORIGINAL_POST entries reach this check.
Common situations: Jike changed its search response schema (field renamed from id); an A/B test returns a new result subtype that still reports type 'ORIGINAL_POST' but has no id; partial/corrupted API responses during rate limiting or login state degradation.
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
- Chess.com stats payload for ${kind} is not an object
- Chess.com stats payload for ${kind}.last is not an object
- Chess.com stats payload for ${kind}.best is not an object
- Chess.com stats payload for ${kind}.record is not an object
- Chess.com game archive entry is not an object
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/052e8f6f925998d0.
Report an issue: GitHub.