jackwener/OpenCLI · error · CommandExecutionError

Failed to parse notifications data

Error message

Failed to parse notifications data

What it means

After navigating to /notifications and running the in-page extraction script, the command validates that the result is an array with Array.isArray and throws CommandExecutionError('Failed to parse notifications data') otherwise. This catches evaluate results that came back undefined/null or in an unexpected shape, meaning the notifications DOM could not be scraped as expected.

Source

Thrown at clis/v2ex/notifications.js:68

            payload = payloadEl.textContent?.trim() || '';
          }

          // fallback to full text cleaning if no payload (e.g. for favorites/thanks)
          let content = payload;
          if (!content) {
            content = text.replace(/\\s+/g, ' ').trim();
            // strip out time from content if present
            if (time && content.includes(time)) {
              content = content.replace(time, '').trim();
            }
          }

          return { type, content, time };
        });
      }
    `);
        if (!Array.isArray(data))
            throw new CommandExecutionError('Failed to parse notifications data');
        const limit = kwargs.limit || 20;
        return data.slice(0, limit);
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-login to V2EX so /notifications renders the real notification list instead of a redirect.
  2. Visit /notifications manually in the automation browser to clear any Cloudflare challenge, then retry.
  3. Add a readiness wait (e.g. waitForSelector for '#Main .box') before evaluate, and raise the 1500ms settle delay if the page loads slowly.
  4. If V2EX changed its markup, update the selector '#Main .box .cell[id^="n_"]' in clis/v2ex/notifications.js.
  5. Log the raw evaluate result (OPENCLI_VERBOSE-style debug) to see what shape actually came back.

Example fix

// before
const data = await page.evaluate(`(async () => { ... })()`);
if (!Array.isArray(data)) throw new CommandExecutionError('Failed to parse notifications data');
// after: wait for items to exist first
await page.goto('https://www.v2ex.com/notifications');
await page.waitForSelector('#Main .box .cell[id^="n_"]', { timeout: 10000 }).catch(() => {});
const data = await page.evaluate(`(async () => { ... })()`);
Defensive patterns

Strategy: type-guard

Validate before calling

await page.goto('https://www.v2ex.com/notifications');
await page.waitForSelector('#Main .box .cell[id^="n_"]', { timeout: 10000 }).catch(() => {});

Type guard

function isNotificationArray(v) {
  return Array.isArray(v) && v.every(x => x && typeof x === 'object' && 'type' in x && 'content' in x);
}

Try / catch

try {
  const rows = await runNotifications({ limit: 20 });
} catch (e) {
  if (/Failed to parse notifications data/.test(e.message)) {
    // check session/login state and page markup, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: page.evaluate returns a non-array — evaluate failed outright (page navigated/closed), the /notifications page rendered something other than the expected '#Main .box .cell[id^="n_"]' list (sign-in redirect, Cloudflare page, empty/changed layout), or the evaluate bridge didn't serialize the async IIFE result correctly.

Common situations: Session expired so V2EX redirected to signin (no .cell[id^=n_] items and unexpected result shape); Cloudflare interstitial served; V2EX changed notifications markup; script string altered so evaluate returns undefined.

Understand the failure class

Related errors


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