jackwener/OpenCLI · error

returned malformed items payload

Error message

 returned malformed items payload

What it means

The Instagram feed response parsed as JSON but did not have the expected shape: feed.items was missing or not an array. getPostFromFeed validates the payload structure before indexing. This means Instagram changed the response envelope or returned an error/status object instead of media items.

Source

Thrown at clis/instagram/unsave.js:35

    columns: ['status', 'user', 'post'],
    pipeline: [
        { navigate: 'https://www.instagram.com' },
        { evaluate: `(async () => {
  const username = \${{ args.username | json }};
  const idx = \${{ args.index }} - 1;
  if (!Number.isInteger(idx) || idx < 0) throw new Error('index must be a positive integer');
  const headers = { 'X-IG-App-ID': '936619743392459' };
  const opts = { credentials: 'include', headers };
  async function readInstagramJson(response, label) {
    try {
      return await response.json();
    } catch {
      throw new Error(label + ' returned invalid JSON');
    }
  }
  function getPostFromFeed(feed, label) {
    if (!feed || typeof feed !== 'object' || !Array.isArray(feed.items)) {
      throw new Error(label + ' returned malformed items payload');
    }
    if (idx >= feed.items.length) throw new Error('Post index ' + (idx + 1) + ' not found');
    const post = feed.items[idx];
    const pkRaw = post?.pk ?? post?.id;
    const pk = typeof pkRaw === 'number' ? String(pkRaw) : (typeof pkRaw === 'string' ? pkRaw.trim() : '');
    if (!/^\\d+$/.test(pk)) throw new Error(label + ' returned malformed post row');
    const caption = typeof post?.caption?.text === 'string' ? post.caption.text.substring(0, 60) : '';
    return { pk, caption };
  }
  function assertOkStatus(payload, label) {
    if (!payload || typeof payload !== 'object' || payload.status !== 'ok') {
      throw new Error(label + ' returned no success evidence');
    }
  }

  // web_profile_info answers HTTP 400 for business accounts; feed-by-username needs no user id. See #2234.
  const r1 = await fetch('https://www.instagram.com/api/v1/feed/user/' + encodeURIComponent(username) + '/username/?count=' + (idx + 1), opts);
  if (!r1.ok) throw new Error(r1.status === 404 ? 'User not found: ' + username : 'HTTP ' + r1.status + ' - make sure you are logged in to Instagram');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Confirm the target account is public and has posts.
  2. Verify you follow the account if it is private.
  3. Check Instagram API changes; update the CLI if the items envelope moved.
Defensive patterns

Strategy: type-guard

Validate before calling

const isFeed = (f) => f && typeof f === 'object' && Array.isArray(f.items);

Type guard

function isItemsPayload(d) {
  return !!d && typeof d === 'object' && Array.isArray(d.items);
}
if (!isItemsPayload(feed)) throw new Error('unexpected feed shape');

Try / catch

try {
  await cli.unsave(user, index);
} catch (e) {
  if (e.message.includes('malformed items payload')) {
    console.error('Feed shape unexpected — is the account public and does it have posts?');
  } else throw e;
}

Prevention

When it happens

Trigger: feed/user/{username}/username/ returns JSON without an items array — empty account, restricted/private profile, or Instagram API shape change.

Common situations: Querying a private account you don't follow; account with zero posts; Instagram A/B response format differences for business accounts.

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