Common Webwright Errors and Format Failures: Troubleshooting Guide

Most Webwright errors stem from nested event loops, missing configuration files, invalid user inputs, or malformed LLM JSON output, each raised by specific modules like runtime.py, _model_config.py, or base.py with distinct resolution paths.

Webwright is a lightweight orchestration framework developed by Microsoft that integrates LLM APIs, browser automation, and tool processing. Because it coordinates multiple runtime components—from asyncio event loops to JSON schema validation—developers frequently encounter specific error families during implementation. This guide examines the root causes of common Webwright errors and format failures as implemented in the microsoft/Webwright repository, providing actionable fixes based on the actual source code structure.

RuntimeError – Active Event Loop Conflicts

Webwright raises RuntimeError when you attempt to invoke run_async from src/webwright/utils/runtime.py while already inside an active asyncio event loop. This commonly occurs in Jupyter notebooks or nested async contexts where the helper expects to be the top-level driver.

The error message indicates that Webwright forbids nested event loops, enforcing a strict single-loop architecture. To resolve this, use await directly inside async functions rather than wrapping calls with run_async, or ensure your script executes outside an active loop.

import asyncio
from webwright.utils.runtime import run_async

async def my_coro():
    return await asyncio.sleep(0)

# Raises RuntimeError inside an existing loop

run_async(my_coro())

Replace run_async(my_coro()) with await my_coro() when operating within an async context.

FileNotFoundError – Missing Configurations and Resources

FileNotFoundError typically originates in three critical modules: src/webwright/tools/_model_config.py for model configurations, src/webwright/tools/image_qa.py for image resources, and src/webwright/environments/local_browser.py for CDP endpoints. These errors trigger when required JSON/YAML configs, image files, or local CDP URLs cannot be located on disk.

Verify the paths passed via CLI flags such as --model-config, --image, or --local-cdp-url. Ensure files are committed to the repository or generated by prior pipeline steps before the tool execution begins.

from webwright.tools._model_config import load_model_config

try:
    cfg = load_model_config("configs/my_model.yaml")
except FileNotFoundError as e:
    print(f"Config file missing: {e}")
    raise

ValueError – Invalid User Input Validation

ValueError emerges during strict validation checks in src/webwright/tools/_model_config.py, prompt building in src/webwright/agents/self_reflection.py and src/webwright/agents/default.py, and workspace command validation in src/webwright/environments/local_workspace.py. These errors indicate logic violations such as unsupported enum values, missing required fields, or mutually exclusive arguments.

The error messages typically cite the offending key explicitly, such as "Provide only one of prompt or prompt_file". Review your CLI flags or JSON payloads to ensure all required fields conform to the expected schema before submission.

FormatError – LLM Output Parsing Failures

FormatError represents the most common failure mode when integrating large language models, raised by _format_error and _format_repair_message in src/webwright/models/base.py. This error occurs when model responses violate the expected JSON schema, such as missing required fields like "role" and "content", or containing stray characters that prevent parsing.

Enable the optional error_log_path parameter in base.yaml to capture raw model responses for analysis. Adjust the format_error_template configuration to include stricter JSON schema hints, or tighten system prompts to enforce valid JSON output structures.

{
  "thoughts": "I need to list files",
  "action": "list_directory",
  "args": "/tmp"
}

The above example fails because it lacks the required "role" field, triggering FormatError in the base model wrapper.

InterruptAgentFlow Signals and TimeoutError

InterruptAgentFlow subclasses—including LimitsExceeded and Submitted—are defined in src/webwright/exceptions.py and raised throughout the agent loop. These are not errors but intentional flow control signals indicating token budget exhaustion or successful task submission. TimeoutError specifically occurs in src/webwright/environments/local_browser.py when the local Chrome DevTools Protocol server fails to become reachable within the configured window.

Increase cdp_wait_timeout_seconds in local_browser.yaml if you encounter TimeoutError on slower machines. For LimitsExceeded errors, expand the configured token budget in your model configuration to accommodate larger contexts.

JSON Decode Errors in Model Responses

json.JSONDecodeError and related ValueError exceptions surface in src/webwright/models/base.py during response handling when the model returns malformed JSON or non-dictionary objects. These parsing failures occur immediately after the API call when the code attempts json.loads on the raw response.

Activate log_raw_responses in your configuration to inspect the exact payload causing the failure. Revise your model prompts to explicitly request JSON object outputs rather than markdown code blocks or plain text.

Step-by-Step Troubleshooting Workflow

Follow this systematic approach to diagnose Webwright failures efficiently:

  1. Identify the error source by examining the stack trace to determine which module raised the exception.
  2. Inspect related configurations to verify that YAML files, image paths, and CLI arguments exist and contain valid data.
  3. Enable verbose logging by setting error_log_path (e.g., logs/error.log) in base.yaml to capture raw model responses and runtime events.
  4. Re-run with isolated steps—test only the model call with webwright run model … to isolate format errors, or only the browser tool with webwright run browser … to verify the CDP endpoint.
  5. Adjust prompts iteratively by editing format_error_template to include stricter JSON schema constraints when FormatError persists.

Practical Error Handling Examples

These patterns demonstrate defensive coding against common Webwright failure modes.

Safely calling run_async from a script:

from webwright.utils.runtime import run_async

async def main_task():
    # Perform LLM calls, browser actions, etc.

    return "done"

result = run_async(main_task())  # Safe when no event loop is running

print(result)

Detecting and retrying on FormatError:

from webwright.models.base import BaseModel
from webwright.exceptions import FormatError

model = BaseModel(...)
try:
    response = await model.run(prompt="Summarize...")
except FormatError as fe:
    print("Model output malformed:", fe.messages)
    # Trigger repair step or abort

Handling image-based tool failures:

from webwright.tools.image_qa import image_qa

try:
    answer = image_qa("path/to/nonexistent.png")
except FileNotFoundError as fnf:
    print(f"Image not found: {fnf}")
    # Prompt user for valid path

Summary

  • RuntimeError in src/webwright/utils/runtime.py prevents nested event loops; use await directly in async contexts.
  • FileNotFoundError indicates missing configs, images, or CDP endpoints; verify all paths before execution.
  • ValueError signals invalid user inputs during validation; check CLI flags and JSON schema compliance.
  • FormatError and JSONDecodeError occur when LLM output violates expected schemas; enable error_log_path and log_raw_responses to debug.
  • TimeoutError requires increasing cdp_wait_timeout_seconds or verifying Chrome installation for local browser automation.

Frequently Asked Questions

How do I fix RuntimeError when calling run_async in Webwright?

This error occurs in src/webwright/utils/runtime.py when you invoke run_async from inside an already-running asyncio event loop, such as in Jupyter notebooks. The utility enforces a strict no-nesting policy to prevent loop conflicts. Replace run_async(coro()) with await coro() inside async functions, or ensure your entry point runs outside an active loop.

What causes FormatError in Webwright and how do I repair it?

FormatError is raised by _format_error in src/webwright/models/base.py when LLM responses fail JSON schema validation, typically due to missing required fields like "role" or malformed syntax. Enable error_log_path in base.yaml to capture the raw output, then adjust the format_error_template configuration or system prompt to enforce stricter JSON object formatting with explicit key requirements.

Why does Webwright raise FileNotFoundError for model configurations?

The load_model_config function in src/webwright/tools/_model_config.py raises this error when it cannot locate YAML/JSON configuration files specified via --model-config paths. Verify that configuration files exist at the specified paths, are properly committed to the repository, or are generated by preceding pipeline steps before the tool execution begins.

How do I troubleshoot TimeoutError with the local browser CDP?

TimeoutError originates in src/webwright/environments/local_browser.py when the Chrome DevTools Protocol endpoint fails to respond within the default wait window, common on slower machines. Increase the cdp_wait_timeout_seconds value in local_browser.yaml to extend the connection timeout, and verify that Chrome is installed with the correct binary path specified in your environment configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →