jackwener/OpenCLI · error · CommandExecutionError

${actionLabel} failed: invalid browser response

Error message

${actionLabel} failed: invalid browser response

What it means

postHupuJson runs a fetch POST inside the browser page and expects page.evaluate to return an object of shape {ok, status, data} (or {ok:false, error}). When the evaluate result is null/undefined or not an object — meaning the in-page script did not return its structured result — it throws CommandExecutionError '<action> failed: invalid browser response'. This guards against browser automation failures rather than API-level errors.

Source

Thrown at clis/hupu/utils.js:306

      } catch (error) {
        return {
          ok: false,
          error: error instanceof Error ? error.message : String(error)
        };
      }
    })()
  `;
}
/**
 * Execute authenticated Hupu JSON requests inside the browser page so
 * cookies and the thread referer come from the live logged-in session.
 */
export async function postHupuJson(page, tid, apiUrl, body, actionLabel, mode = 'default') {
    const referer = getHupuThreadUrl(tid);
    await page.goto(referer);
    const result = await page.evaluate(buildBrowserJsonPostScript(apiUrl, body, mode));
    if (!result || typeof result !== 'object') {
        throw new CommandExecutionError(`${actionLabel} failed: invalid browser response`);
    }
    if (result.status === 401 || result.status === 403) {
        throw new AuthRequiredError('bbs.hupu.com', `${actionLabel} failed: please log in to Hupu first`);
    }
    if (result.error) {
        throw new CommandExecutionError(`${actionLabel} failed: ${result.error}`);
    }
    if (!result.ok) {
        const detail = result.data?.msg || result.data?.message || `HTTP ${result.status ?? 'unknown'}`;
        throw new CommandExecutionError(`${actionLabel} failed: ${detail}`);
    }
    return result.data ?? {};
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command — a transient tab crash or navigation race often resolves on retry.
  2. Ensure the browser session stays open and no navigation happens while the command runs.
  3. Confirm the thread URL (tid) loads correctly first; a failing page.goto can leave the page in a bad state.
  4. Upgrade/verify the browser automation driver if evaluate consistently returns undefined.
  5. Check network connectivity to bbs.hupu.com; a fetch failure should normally return {ok:false,error}, so a bare non-object implies the script never completed.

Example fix

// before
const result = await page.evaluate(buildBrowserJsonPostScript(apiUrl, body, mode));
// after — validate the page is ready before evaluating
await page.goto(referer, { waitUntil: 'domcontentloaded' });
const result = await page.evaluate(buildBrowserJsonPostScript(apiUrl, body, mode));
if (!result || typeof result !== 'object') throw new CommandExecutionError(`${actionLabel} failed: invalid browser response`);
Defensive patterns

Strategy: type-guard

Validate before calling

// validate prerequisites before the in-page POST
if (page.isClosed?.()) throw new Error('browser page already closed');
await page.goto(getHupuThreadUrl(tid), { waitUntil: 'domcontentloaded' });
if (!/^\d+$/.test(String(tid))) throw new Error(`invalid tid: ${tid}`);

Type guard

function isBrowserPostResult(r) {
  return typeof r === 'object' && r !== null &&
    (typeof r.ok === 'boolean') &&
    ('status' in r || 'error' in r);
}
// usage
const result = await page.evaluate(script);
if (!isBrowserPostResult(result)) throw new CommandExecutionError('invalid browser response');

Try / catch

try {
  await postHupuJson(page, tid, apiUrl, body, 'Like reply');
} catch (err) {
  if (/invalid browser response/.test(err.message)) {
    await sleep(1000);
    return retryOnce(); // transient evaluate/navigation failure
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling postHupuJson (like/unlike/reply commands) when page.evaluate returns nothing: the in-page async script was interrupted, the page navigated/closed mid-evaluate, the browser context was destroyed, or evaluate deserialization failed.

Common situations: The automated browser tab crashed or was closed during the POST, the page navigated away (redirect) while evaluate was pending, a Playwright/Puppeteer issue evaluating async script strings, or a network disconnect killing the in-page fetch so the script never resolved.

Related errors


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