can1357/oh-my-pi · error · ToolError

${operation} requires an active cmux browser run

Error message

${operation} requires an active cmux browser run

What it means

CmuxTab methods that need run-scoped state (abort signal, timeouts, run scope) call `#requireRunContext(operation)`, which throws this ToolError when `#runContext` is unset. Browser operations are only valid inside an active cmux browser run; calling them outside one has no execution context.

Source

Thrown at packages/coding-agent/src/tools/browser/cmux/cmux-tab.ts:1130

		}
	}

	#normalizeGeometry(value: unknown): CmuxGeometry {
		const object = value && typeof value === "object" ? (value as Record<string, unknown>) : {};
		return {
			innerWidth: numberFrom(object.innerWidth, DEFAULT_VIEWPORT.width),
			innerHeight: numberFrom(object.innerHeight, DEFAULT_VIEWPORT.height),
			dpr: numberFrom(object.dpr, DEFAULT_VIEWPORT.deviceScaleFactor ?? 1),
			scrollX: numberFrom(object.scrollX, 0),
			scrollY: numberFrom(object.scrollY, 0),
			scrollWidth: numberFrom(object.scrollWidth, DEFAULT_VIEWPORT.width),
			scrollHeight: numberFrom(object.scrollHeight, DEFAULT_VIEWPORT.height),
		};
	}

	#requireRunContext(operation: string): RunContext {
		if (!this.#runContext) {
			throw new ToolError(`${operation} requires an active cmux browser run`);
		}
		return this.#runContext;
	}
}

class CmuxResponse {
	readonly #record: CmuxResponseRecord;

	constructor(record: CmuxResponseRecord) {
		this.#record = record;
	}

	url(): string {
		return this.#record.url;
	}

	status(): number {
		return this.#record.status;

View on GitHub (pinned to 9690622007)

Solutions

  1. Move the browser calls inside the active cmux browser run block so the run context is installed.
  2. Don't cache CmuxTab/page references across runs — obtain them within each run's scope.
  3. Guard async callbacks: check the run is still active (or abort them with the run's signal) before issuing browser calls.

Example fix

// before
const tab = await browser.openTab();
setTimeout(() => tab.navigate(url), 5000); // fires after run ended
// after
await withBrowserRun(async () => {
  const tab = await browser.openTab();
  await tab.navigate(url);
});
Defensive patterns

Strategy: validation

Validate before calling

// structure code so all browser calls live inside the run scope
if (!runIsActive) throw new Error('browser API used outside cmux run');
await withBrowserRun(async (tab) => { /* all tab calls here */ });

Prevention

When it happens

Trigger: Invoking tab/page/browser methods (navigation, eval, screenshots, wait) before a browser run starts, after it finished/aborted, or from a detached/reused CmuxTab instance whose run ended.

Common situations: Calling the facade from test setup code outside the run helper; keeping a tab reference after the run's finally block cleared the context; async callbacks (timers, event handlers) firing after the run completed.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/c0730259e1e2d594. Report an issue: GitHub.