jackwener/OpenCLI · error · CommandExecutionError
Browser session required for medium posts
Error message
Browser session required for medium posts
What it means
loadMediumPosts scrapes Medium user pages through a browser (page.goto/wait/evaluate). It requires an active browser session; when page is null/undefined it throws CommandExecutionError 'Browser session required for medium posts' instead of attempting a headless HTTP fetch.
Source
Thrown at clis/medium/utils.js:13
import { CommandExecutionError } from '@jackwener/opencli/errors';
export function buildMediumTagUrl(topic) {
return topic ? `https://medium.com/tag/${encodeURIComponent(topic)}` : 'https://medium.com/tag/technology';
}
export function buildMediumSearchUrl(keyword) {
return `https://medium.com/search?q=${encodeURIComponent(keyword)}`;
}
export function buildMediumUserUrl(username) {
return username.startsWith('@') ? `https://medium.com/${username}` : `https://medium.com/@${username}`;
}
export async function loadMediumPosts(page, url, limit) {
if (!page)
throw new CommandExecutionError('Browser session required for medium posts');
await page.goto(url);
await page.wait({ selector: 'article', timeout: 5 });
const data = await page.evaluate(`
(async () => {
await new Promise((resolve) => setTimeout(resolve, 3000));
const limit = ${Math.max(1, Math.min(limit, 50))};
const normalize = (value) => (value || '').replace(/\\s+/g, ' ').trim();
const posts = [];
const seen = new Set();
for (const article of Array.from(document.querySelectorAll('article'))) {
try {
const titleEl = article.querySelector('h2, h3, h1');
const title = normalize(titleEl?.textContent);
if (!title) continue;
const linkEl = titleEl?.closest('a') || article.querySelector('a[href*="/@"], a[href*="/p/"]');View on GitHub (pinned to 49907e53dc)
Solutions
- Start the browser session/Browser Bridge before running the medium posts command (per the CLI's browser setup instructions).
- Verify the page object is passed to loadMediumPosts — never call it with an undefined page in custom scripts.
- Re-open the browser if a previous session crashed, then rerun the command.
- If you need data without a browser, use the RSS-based medium tag command instead, which does not require a page.
Example fix
// before await loadMediumPosts(null, 'https://medium.com/@user', 5); // throws // after const page = await browser.newPage(); await loadMediumPosts(page, 'https://medium.com/@user', 5);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!page) {
throw new Error('Start the browser session/Browser Bridge before loading medium posts');
} Type guard
function hasBrowserPage(p) {
return p != null && typeof p.goto === 'function' && typeof p.evaluate === 'function';
} Try / catch
try {
await loadMediumPosts(page, url, limit);
} catch (e) {
if (/Browser session required/.test(e.message)) {
const page = await startBrowserBridge();
await loadMediumPosts(page, url, limit);
} else throw e;
} Prevention
- Always initialize the browser/Browser Bridge before browser-based commands.
- Assert page existence in wrapper scripts before calling loadMediumPosts.
- Recreate the page after crashes instead of reusing a dead reference.
- Prefer the RSS-based medium tag command when a browser is unavailable.
When it happens
Trigger: Calling loadMediumPosts(page=null, url, limit) or invoking the wrapping medium posts command without a browser session/bridge established (e.g. browser not started, Browser Bridge not connected, session closed before the call).
Common situations: Running the command in an environment without a logged-in/available browser; forgetting to initialize the browser adapter before calling the medium posts helper; a previously-open page that crashed or was closed leaving `page` falsy.
Related errors
- Browser session required for linkedin-learning trending
- Browser session required for gmail attachments
- Browser session required for gmail labels
- Browser session required for linkedin connect
- medium tag request failed: ${err?.message ?? err}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2d6696ce5bf0dd98.
Report an issue: GitHub.