anthropics/skills · error · RuntimeError

Server failed to start on port {server['port']} within {args

Error message

Server failed to start on port {server['port']} within {args.timeout}s

What it means

with_server.py starts one or more dev servers via shell commands and polls each port with is_server_ready(); if the port never accepts connections within --timeout seconds it raises this RuntimeError. The named port identifies which server['cmd'] failed to become reachable.

Source

Thrown at skills/webapp-testing/scripts/with_server.py:80

    try:
        # Start all servers
        for i, server in enumerate(servers):
            print(f"Starting server {i+1}/{len(servers)}: {server['cmd']}")

            # Use shell=True to support commands with cd and &&
            process = subprocess.Popen(
                server['cmd'],
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            server_processes.append(process)

            # Wait for this server to be ready
            print(f"Waiting for server on port {server['port']}...")
            if not is_server_ready(server['port'], timeout=args.timeout):
                raise RuntimeError(f"Server failed to start on port {server['port']} within {args.timeout}s")

            print(f"Server ready on port {server['port']}")

        print(f"\nAll {len(servers)} server(s) ready")

        # Run the command
        print(f"Running: {' '.join(args.command)}\n")
        result = subprocess.run(args.command)
        sys.exit(result.returncode)

    finally:
        # Clean up all servers
        print(f"\nStopping {len(server_processes)} server(s)...")
        for i, process in enumerate(server_processes):
            try:
                process.terminate()
                process.wait(timeout=5)
            except subprocess.TimeoutExpired:

View on GitHub (pinned to f6656c1256)

Solutions

  1. Run the server command exactly as passed to with_server.py in a separate terminal and watch it bind — confirm the port matches server['port']
  2. Raise the budget: pass a larger --timeout (e.g. --timeout 120) for cold starts
  3. Free a occupied port: `lsof -ti :PORT | xargs kill` (or pick another port)
  4. Fix the server command so it listens on the expected interface/port (e.g. --host 127.0.0.1 --port 3000)

Example fix

# before
python scripts/with_server.py --port 3000 -- npm run dev -- ./tests
# after: longer budget and explicit matching port
python scripts/with_server.py --port 3000 --timeout 120 -- npm run dev -- --port 3000 -- ./tests
Defensive patterns

Strategy: validation

Validate before calling

import socket

def port_free(port: int) -> bool:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.connect_ex(("127.0.0.1", port)) != 0

Try / catch

try:
    run_with_server(servers, cmd, timeout=120)
except RuntimeError as e:
    if "failed to start" in str(e):
        dump_server_logs()  # capture the Popen stdout/stderr you piped
    raise

Prevention

When it happens

Trigger: Passing a server command that exits immediately (bad flag, missing dependency) so nothing ever listens; the server binding to a different port than server['port']; slow cold starts (first install/compile) exceeding args.timeout; the port already occupied by a stale process so the new server aborts.

Common situations: Local dev where npm install/dev-server startup exceeds the default timeout; server bound to 127.0.0.1 vs 0.0.0.0 mismatch with the readiness probe; port conflicts from a previous unclean run; wrong port number in the JSON/CLI config given to with_server.py.

Understand the failure class

Related errors


AI-assisted analysis of anthropics/skills@f6656c1256 (2026-08-14). Data as JSON: /api/errors/ddadd0e697c65638. Report an issue: GitHub.