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.

Solutions

  1. Capture the raw notification to confirm the users field shape in the new payload
  2. Retry — determine if only specific notification types (aggregations) trigger it and filter those out
  3. Patch mapNotification to default users to an empty array: `const users = Array.isArray(actionItem.users) ? actionItem.users : [];`
  4. If a singular actor field exists, normalize it: wrap a non-array user object into [user] before mapping
  5. 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

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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/0b99c9f62dce5636. Report an issue: GitHub.

Appendix: 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)