jackwener/OpenCLI · error · CommandExecutionError

Jike notifications API returned a malformed action item

Error message

Jike notifications API returned a malformed action item

What it means

CommandExecutionError thrown by mapNotification when a notification's actionItem field is missing, not an object, or is an array. actionItem carries the acting users and behavior content for the notification; without a valid object the row cannot be built, so the library treats the response as malformed and aborts the command.

Source

Thrown at clis/jike/notifications.js:57

    if (sourceType.includes('MENTION')) return '提到了你';
    if (sourceType.includes('REPLY')) return '回复了你';
    return notification.type;
}

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 {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Capture the raw notification JSON to see what replaced or nulled actionItem
  2. Retry the command — if only notifications about deleted content trigger it, they may disappear from the feed over time
  3. Patch mapNotification to skip such items (return null and filter) or to fall back to an alternate field (e.g. referenceItem) when actionItem is absent
  4. Check whether a new notification type correlates with the missing actionItem and add a dedicated mapping branch
  5. Update TYPE_LABELS/handling for the new payload shape so the row can be constructed

Example fix

// before
if (!actionItem || typeof actionItem !== 'object' || Array.isArray(actionItem)) {
  throw new CommandExecutionError('Jike notifications API returned a malformed action item');
}
// after: skip instead of failing
if (!actionItem || typeof actionItem !== 'object' || Array.isArray(actionItem)) {
  return null; // filtered by caller
}
Defensive patterns

Strategy: type-guard

Validate before calling

function hasActionItem(n) {
  const a = n?.actionItem;
  return a != null && typeof a === 'object' && !Array.isArray(a);
}
const usable = body.data.filter(n => hasNotificationId(n) && hasNotificationType(n) && hasActionItem(n));

Type guard

function hasValidActionItem(n) {
  return typeof n === 'object' && n !== null &&
    n.actionItem !== null && typeof n.actionItem === 'object' && !Array.isArray(n.actionItem);
}

Try / catch

try {
  rows = await jikeNotifications(page, limit);
} catch (e) {
  if (/malformed action item$/.test(e.message)) {
    rows = (await fetchRaw()).filter(n => n.actionItem && typeof n.actionItem === 'object' && !Array.isArray(n.actionItem));
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the jike notifications command when an item from /1.0/notifications/list has id and type but actionItem is null/undefined/an array — e.g. notifications referencing deleted content or new notification categories with a different payload layout.

Common situations: Jike API change relocating action data to a new field; deleted/recalled action content causing null actionItem; system notifications without an action payload; mixed old/new payload versions during API rollout.

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/5c7baf1183870918. Report an issue: GitHub.