jackwener/OpenCLI · error · CommandExecutionError
Jike notifications API returned a malformed users list
Error message
Jike notifications API returned a malformed users list
What it means
CommandExecutionError thrown by mapNotification when a notification's actionItem.users field is not an array. users holds the actors (with screenName) for the notification action; the code maps over it to build the 'user' column, so a missing or non-array users list makes the row impossible to produce and the library aborts with this error.
Source
Thrown at clis/jike/notifications.js:60
}
function cleanContent(value) {
return typeof value === 'string' ? value.replace(/\n/g, ' ').slice(0, 100) : '';
}
function mapNotification(notification) {
if (!notification || typeof notification !== 'object' || typeof notification.id !== 'string' || !notification.id) {
throw new CommandExecutionError('Jike notifications API returned a malformed notification');
}
if (typeof notification.type !== 'string' || !notification.type) {
throw new CommandExecutionError('Jike notifications API returned a notification without a type');
}
const actionItem = notification.actionItem;
if (!actionItem || typeof actionItem !== 'object' || Array.isArray(actionItem)) {
throw new CommandExecutionError('Jike notifications API returned a malformed action item');
}
if (!Array.isArray(actionItem.users)) {
throw new CommandExecutionError('Jike notifications API returned a malformed users list');
}
const names = actionItem.users.map((user) => {
if (!user || typeof user !== 'object') {
throw new CommandExecutionError('Jike notifications API returned a malformed user');
}
return typeof user.screenName === 'string' ? user.screenName : '';
}).filter(Boolean);
const referenceItem = notification.referenceItem;
const referenceContent = referenceItem && typeof referenceItem === 'object' && !Array.isArray(referenceItem)
? referenceItem.content
: '';
const time = typeof notification.createdAt === 'string'
? notification.createdAt
: (typeof notification.updatedAt === 'string' ? notification.updatedAt : '');
return {
type: resolveActionLabel(notification, actionItem),
user: names.join('、'),
content: cleanContent(actionItem.content || referenceContent),View on GitHub (pinned to 49907e53dc)
Solutions
- Capture the raw notification to confirm the users field shape in the new payload
- Retry — determine if only specific notification types (aggregations) trigger it and filter those out
- Patch mapNotification to default users to an empty array: `const users = Array.isArray(actionItem.users) ? actionItem.users : [];`
- If a singular actor field exists, normalize it: wrap a non-array user object into [user] before mapping
- Update TYPE_LABELS/mapping for the new aggregated-notification shape upstream
Example fix
// before
if (!Array.isArray(actionItem.users)) {
throw new CommandExecutionError('Jike notifications API returned a malformed users list');
}
// after: normalize instead of throwing
const users = Array.isArray(actionItem.users)
? actionItem.users
: (actionItem.users && typeof actionItem.users === 'object' ? [actionItem.users] : []); Defensive patterns
Strategy: type-guard
Validate before calling
function hasUsersList(n) {
return Array.isArray(n?.actionItem?.users);
}
const usable = body.data.filter(n => hasNotificationId(n) && hasNotificationType(n) && hasActionItem(n) && hasUsersList(n)); Type guard
function hasValidUsersList(n) {
return Array.isArray(n?.actionItem?.users) &&
n.actionItem.users.every(u => u != null && typeof u === 'object');
} Try / catch
try {
rows = await jikeNotifications(page, limit);
} catch (e) {
if (/malformed users list$/.test(e.message)) {
rows = (await fetchRaw()).map(n => {
const a = n.actionItem;
if (a && typeof a === 'object' && !Array.isArray(a) && !Array.isArray(a.users)) {
return { ...n, actionItem: { ...a, users: a.users ? [a.users] : [] } };
}
return n;
});
} else throw e;
} Prevention
- Normalize actionItem.users to an array (wrap singular actor objects) before mapping
- Validate every users element is an object with a screenName string
- Keep a sample-based contract test on the notifications payload
- Filter out aggregated-notification shapes your version does not support
When it happens
Trigger: Calling the jike notifications command when an item has valid id/type/actionItem object but actionItem.users is undefined, null, or a non-array — e.g. aggregated notifications changing shape or single-actor notifications using a scalar user field.
Common situations: Jike API rollout switching aggregated notifications to a different users representation; batched notifications omitting users; new notification category with a singular actor field; partial payloads during pagination.
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
- Jike notifications API returned a malformed notification
- Jike notifications API returned a notification without a typ
- Jike notifications API returned a malformed action item
- Bilibili creator comparison API returned malformed list data
- Bilibili creator comparison returned a malformed manuscript
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0b99c9f62dce5636.
Report an issue: GitHub.