{"record":{"id":"ccf526b65ba07480","repo":"jackwener/OpenCLI","slug":"browser-page-required-ccf526","errorCode":null,"errorMessage":"Browser page required","messagePattern":"Browser page required","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/v2ex/me.js","lineNumber":18,"sourceCode":"/**\n * V2EX Me (Profile/Balance) adapter.\n */\nimport { CommandExecutionError } from '@jackwener/opencli/errors';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\ncli({\n    site: 'v2ex',\n    name: 'me',\n    access: 'read',\n    description: 'V2EX 获取个人资料 (余额/未读提醒)',\n    domain: 'www.v2ex.com',\n    strategy: Strategy.COOKIE,\n    browser: true,\n    args: [],\n    columns: ['username', 'balance', 'unread_notifications', 'daily_reward_ready'],\n    func: async (page) => {\n        if (!page)\n            throw new CommandExecutionError('Browser page required');\n        if (process.env.OPENCLI_VERBOSE) {\n            console.error('[opencli:v2ex] Navigating to /');\n        }\n        await page.goto('https://www.v2ex.com/');\n        // Cloudflare challenge bypass wait\n        for (let i = 0; i < 5; i++) {\n            await new Promise(r => setTimeout(r, 1500));\n            const title = await page.evaluate(`() => document.title`);\n            if (!title?.includes('Just a moment'))\n                break;\n            if (process.env.OPENCLI_VERBOSE)\n                console.error('[opencli:v2ex] Waiting for Cloudflare...');\n        }\n        // Evaluate DOM to extract user profile\n        const data = await page.evaluate(`\n      async () => {\n        let username = 'Unknown';\n        const navLinks = Array.from(document.querySelectorAll('a.top')).map(a => a.textContent?.trim());","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/v2ex/me.js#L1-L36","documentation":"Same guard as the daily command: the v2ex me command declares browser:true under Strategy.COOKIE and throws CommandExecutionError('Browser page required') when its func is invoked with a falsy page. It prevents a crash on page.goto when the browser layer did not supply a page.","triggerScenarios":"Invoking the v2ex me command when browser provisioning failed or was skipped — browser binary missing, launch error, or calling the registered func directly without a page argument.","commonSituations":"Headless CI container without Chromium; playwright browsers not installed; browser user-data-dir locked by another process; programmatic misuse calling func(undefined).","solutions":["Install the browser runtime and system deps (e.g. playwright install chromium / install-deps).","Invoke the command through the CLI so the registry launches the browser and passes a page.","Check prior log lines for the underlying browser launch failure and resolve it (profile lock, missing executable).","Retry in a normal desktop environment to rule out sandbox/display issues in headless mode."],"exampleFix":"// before\nawait meFunc(undefined); // CommandExecutionError: Browser page required\n// after: run via registry\n// $ opencli v2ex me","handlingStrategy":"validation","validationCode":"if (!page || typeof page.goto !== 'function') {\n  throw new Error('Browser page unavailable — verify browser runtime is installed and invoke via the CLI');\n}","typeGuard":"function hasPage(p) {\n  return !!p && typeof p === 'object' && typeof p.goto === 'function' && typeof p.evaluate === 'function';\n}","tryCatchPattern":"try {\n  await runMeCommand();\n} catch (e) {\n  if (e.message === 'Browser page required') {\n    // provision/repair browser environment, then retry\n  } else throw e;\n}","preventionTips":["Ensure the browser binary and OS dependencies are installed in the execution environment.","Always launch v2ex commands through the registry so the page is injected.","Avoid concurrent runs sharing one browser user-data-dir (profile lock).","Verify page provisioning with a trivial goto in CI before running site commands."],"tags":["browser","environment","null-check"],"backgroundTag":"browser-page-not-available","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}