Documentation Index Fetch the complete documentation index at: https://docs.webrun.ai/llms.txt
Use this file to discover all available pages before exploring further.
Session Issues
Session Stuck in Pending State
Symptoms:
Session status remains pending indefinitely
Session never transitions to active state
No browser instance appears to be assigned
Common Causes:
No available browser instances
System experiencing high load
Network connectivity issues
Resource allocation bottleneck
Solutions:
Wait and Check Status
// Poll session status for up to 30 seconds
async function waitForSessionActive ( sessionId , apiKey , maxWait = 30000 ) {
const startTime = Date . now ();
while ( Date . now () - startTime < maxWait ) {
const response = await fetch (
`https://connect.webrun.ai/start/session-status/ ${ sessionId } ` ,
{
headers: { "Authorization" : `Bearer ${ apiKey } ` }
}
);
const data = await response . json ();
if ( data . status === "active" ) {
return data ;
}
if ( data . status === "failed" ) {
throw new Error ( "Session failed to start" );
}
await new Promise ( r => setTimeout ( r , 2000 ));
}
throw new Error ( "Session stuck in pending state" );
}
Terminate and Recreate
// If session is stuck, terminate and create new one
await fetch ( "https://connect.webrun.ai/start/send-message" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
message: { actionType: "state" , newState: "terminate" }
})
});
// Create new session
const newSession = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({ prompt })
});
Check System Status
Visit status.webrun.ai
Look for ongoing incidents or maintenance
Check response times and success rates
Contact Support
If issue persists for > 2 minutes
Provide session ID and timestamp
Include error logs if available
Prevention:
Implement timeout logic when creating sessions
Use retry logic with exponential backoff
Monitor system status before critical operations
Tasks Timing Out
Symptoms:
Tasks return TASK_TIMEOUT error
Tasks exceed maxDuration limit
Incomplete results with timeout message
Common Causes:
Complex pages with heavy JavaScript
Slow network connections
Task requires multiple page loads
Website has anti-bot protections
Task instructions too complex
Solutions:
Increase Maximum Duration
const response = await fetch ( "https://connect.webrun.ai/start/run-task" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
prompt: "Complex multi-step task" ,
maxDuration: 180000 // 3 minutes instead of default 60s
})
});
Break Down Complex Tasks
// Instead of one complex task:
// "Search for products, filter by price, add to cart, and checkout"
// Break into multiple simpler tasks:
const tasks = [
"Navigate to example.com and search for 'laptop'" ,
"Filter results by price range $500-$1000" ,
"Click on the first product" ,
"Add the product to cart"
];
for ( const task of tasks ) {
const result = await runTask ( sessionId , task , apiKey );
console . log ( `Completed: ${ task } ` );
}
Use Starting URL
// Skip navigation time by starting at target page
const session = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
prompt: "Fill out the contact form" ,
startingUrl: "https://example.com/contact" // Skip homepage
})
});
Optimize Task Instructions
// Vague - may cause exploration and timeouts
prompt : "Find information about pricing"
// Specific - faster execution
prompt : "Click the 'Pricing' link in the navigation menu"
Prevention:
Set realistic maxDuration based on task complexity
Test tasks on fast network first
Monitor task execution times
Keep task instructions specific and focused
Tasks Completing But No Result Returned
Symptoms:
Polling returns pending: true indefinitely
Task appears stuck even though browser finished
No error message returned
Common Causes:
Task is still genuinely running
Network issue between browser instance and API
Result notification was lost
WebSocket connection dropped
Solutions:
Continue Polling with Timeout
async function pollWithTimeout ( sessionId , taskId , apiKey , maxTime = 300000 ) {
const startTime = Date . now ();
while ( Date . now () - startTime < maxTime ) {
const response = await fetch (
`https://connect.webrun.ai/task/ ${ sessionId } / ${ taskId } ` ,
{
headers: { "Authorization" : `Bearer ${ apiKey } ` }
}
);
const data = await response . json ();
if ( ! data . pending ) {
return data ;
}
// Wait before next poll
await new Promise ( r => setTimeout ( r , 2000 ));
}
throw new Error ( "Task polling timeout - no result received" );
}
Check WebSocket Events
// If using WebSocket, monitor for task_completed event
const ws = new WebSocket ( `wss://connect.webrun.ai/ws?sessionId= ${ sessionId } ` );
ws . onmessage = ( event ) => {
const data = JSON . parse ( event . data );
if ( data . type === "task_completed" ) {
console . log ( "Task completed:" , data );
}
};
Terminate and Retry
// If stuck for too long, terminate and retry
await fetch ( "https://connect.webrun.ai/start/send-message" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
message: { actionType: "state" , newState: "stop" }
})
});
// Wait a moment then retry
await new Promise ( r => setTimeout ( r , 2000 ));
const retryResult = await runTask ( sessionId , prompt , apiKey );
Prevention:
Use WebSocket for real-time updates
Implement polling with timeouts
Monitor both polling and WebSocket channels
High Token Usage / Unexpected Costs
Symptoms:
Tasks consuming more tokens than expected
Costs higher than estimated
usage object shows large token counts
Common Causes:
Complex pages with lots of DOM elements
Multiple failed attempts and retries
Long-running tasks with many interactions
Not using token limits
Navigation to unnecessary pages
Solutions:
Set Token Limits
const response = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
prompt: "Search for products" ,
maxInputTokens: 10000 , // Limit context size
maxOutputTokens: 2000 // Limit response length
})
});
Use Starting URL
// Skip homepage navigation - saves tokens
const session = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
prompt: "Fill search form" ,
startingUrl: "https://example.com/search" // Go directly to target
})
});
Block Unnecessary Domains
const session = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
prompt: "Read article content"
})
});
Simplify Task Instructions
// Verbose - may cause exploration
prompt : "Navigate around the site and find pricing information, compare different plans, and tell me about the features"
// Concise - direct execution
prompt : "Click 'Pricing' in navigation and extract plan names and prices"
Monitor Usage
const result = await pollForResult ( sessionId , taskId , apiKey );
console . log ( "Token Usage:" , {
input: result . usage . inputTokens ,
output: result . usage . outputTokens ,
cost: result . usage . cost
});
// Track cumulative costs
totalCost += result . usage . cost ;
Prevention:
Always set maxInputTokens and maxOutputTokens
Use startingUrl when possible
Block ad networks and analytics domains
Keep tasks focused and specific
Test on simple pages first
Guardrails & Interaction Issues
Guardrails Triggering Unexpectedly
Symptoms:
Agent frequently asks for input
Tasks pause for user confirmation
guardrail_trigger events fire often
Common Causes:
Task instructions are ambiguous
Website requires login/authentication
CAPTCHA or security check encountered
Agent uncertain about next action
Multiple valid options available
Solutions:
Make Instructions More Specific
// Ambiguous - may trigger guardrail
prompt : "Buy something"
// Specific - clear action
prompt : "Add the first search result to cart, do not proceed to checkout"
Provide Credentials Upfront
const session = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
prompt: "Login using username 'user@example.com' and password 'myPassword123', then navigate to dashboard"
})
});
Handle Guardrails Programmatically
async function handleGuardrails ( sessionId , apiKey ) {
const ws = new WebSocket ( `wss://connect.webrun.ai/ws?sessionId= ${ sessionId } ` );
ws . onmessage = async ( event ) => {
const data = JSON . parse ( event . data );
if ( data . type === "guardrail_trigger" ) {
console . log ( "Guardrail:" , data . data . value );
// Provide automated response
let response ;
if ( data . data . value . includes ( "login" )) {
response = "Yes, use the credentials provided earlier" ;
} else if ( data . data . value . includes ( "confirm" )) {
response = "Yes, proceed" ;
} else {
// Get user input
response = await getUserInput ( data . data . value );
}
// Resume with response
await fetch ( "https://connect.webrun.ai/start/send-message" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
message: {
actionType: "guardrail" ,
prompt: response ,
newState: "resume"
}
})
});
}
};
}
Avoid Sites Requiring Auth
// Block login-required domains
const session = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
prompt: "Research product information"
})
});
Prevention:
Write clear, unambiguous task instructions
Provide all necessary information upfront
Test tasks on public pages first
Handle common guardrail scenarios programmatically
Streaming & Connection Issues
Video Stream Not Loading
Symptoms:
Streaming endpoint returns errors
Video player shows no content
Connection timeout on stream URL
Common Causes:
Session not active yet
Invalid session ID
Network/firewall blocking WebRTC
Browser instance crashed
Solutions:
Verify Session is Active
async function getStreamUrl ( sessionId , apiKey ) {
// Check session status first
const statusResponse = await fetch (
`https://connect.webrun.ai/start/session-status/ ${ sessionId } ` ,
{
headers: { "Authorization" : `Bearer ${ apiKey } ` }
}
);
const status = await statusResponse . json ();
if ( status . status !== "active" ) {
throw new Error ( `Session not ready: ${ status . status } ` );
}
// Get stream URL
return `https://connect.webrun.ai/stream/ ${ sessionId } ` ;
}
Check Network Configuration
// Ensure WebRTC ports are not blocked
// Required ports: TCP 443, UDP 49152-65535
// Test connection
const streamUrl = `https://connect.webrun.ai/stream/ ${ sessionId } ` ;
const testResponse = await fetch ( streamUrl );
if ( ! testResponse . ok ) {
console . error ( "Stream not accessible:" , testResponse . status );
}
Use Alternative Streaming Methods
// If WebRTC fails, try SSE for updates
const eventSource = new EventSource (
`https://connect.webrun.ai/stream/sse/ ${ sessionId } ?apiKey= ${ apiKey } `
);
eventSource . onmessage = ( event ) => {
const data = JSON . parse ( event . data );
console . log ( "Stream update:" , data );
};
Related:
WebSocket Connection Issues
Symptoms:
WebSocket fails to connect
Connection drops frequently
Events not received
Common Causes:
Invalid API key or session ID
Firewall blocking WebSocket connections
Network instability
Session expired
Solutions:
Implement Reconnection Logic
function connectWebSocket ( sessionId , apiKey , maxRetries = 3 ) {
let retries = 0 ;
function connect () {
const ws = new WebSocket (
`wss://connect.webrun.ai/ws?sessionId= ${ sessionId } &apiKey= ${ apiKey } `
);
ws . onopen = () => {
console . log ( "WebSocket connected" );
retries = 0 ;
};
ws . onerror = ( error ) => {
console . error ( "WebSocket error:" , error );
};
ws . onclose = ( event ) => {
console . log ( "WebSocket closed:" , event . code );
// Attempt reconnection
if ( retries < maxRetries ) {
retries ++ ;
const delay = Math . min ( 1000 * Math . pow ( 2 , retries ), 10000 );
console . log ( `Reconnecting in ${ delay } ms...` );
setTimeout ( connect , delay );
}
};
ws . onmessage = ( event ) => {
const data = JSON . parse ( event . data );
handleEvent ( data );
};
return ws ;
}
return connect ();
}
Fall Back to Polling
let ws = null ;
let pollingInterval = null ;
try {
ws = connectWebSocket ( sessionId , apiKey );
} catch ( error ) {
console . log ( "WebSocket failed, falling back to polling" );
// Poll every 2 seconds
pollingInterval = setInterval ( async () => {
const result = await fetch (
`https://connect.webrun.ai/task/ ${ sessionId } / ${ taskId } ` ,
{
headers: { "Authorization" : `Bearer ${ apiKey } ` }
}
);
const data = await result . json ();
if ( ! data . pending ) {
clearInterval ( pollingInterval );
handleResult ( data );
}
}, 2000 );
}
Prevention:
Implement automatic reconnection
Have polling fallback ready
Monitor connection health
Use heartbeat/ping messages
Polling Not Working
Symptoms:
Polling requests return 404
Task ID not recognized
No updates on task status
Common Causes:
Incorrect task ID or session ID
Task already completed and cleaned up
Session expired
Network request failing
Solutions:
Verify IDs are Correct
// Store task ID immediately after creation
const taskResponse = await fetch ( "https://connect.webrun.ai/start/run-task" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
prompt: "Navigate to example.com"
})
});
const taskData = await taskResponse . json ();
const taskId = taskData . taskId ;
console . log ( "Created task:" , taskId , "in session:" , sessionId );
// Use exact IDs for polling
const result = await fetch (
`https://connect.webrun.ai/task/ ${ sessionId } / ${ taskId } ` ,
{
headers: { "Authorization" : `Bearer ${ apiKey } ` }
}
);
Handle Errors Gracefully
async function pollTask ( sessionId , taskId , apiKey ) {
try {
const response = await fetch (
`https://connect.webrun.ai/task/ ${ sessionId } / ${ taskId } ` ,
{
headers: { "Authorization" : `Bearer ${ apiKey } ` }
}
);
if ( response . status === 404 ) {
throw new Error ( "Task or session not found - may have expired" );
}
if ( ! response . ok ) {
const error = await response . json ();
throw new Error ( error . error || "Polling failed" );
}
return await response . json ();
} catch ( error ) {
console . error ( "Polling error:" , error . message );
throw error ;
}
}
Check Session is Still Active
// Before polling, verify session exists
const sessionStatus = await fetch (
`https://connect.webrun.ai/start/session-status/ ${ sessionId } ` ,
{
headers: { "Authorization" : `Bearer ${ apiKey } ` }
}
);
const status = await sessionStatus . json ();
if ( status . error || status . status === "terminated" ) {
throw new Error ( "Session no longer active" );
}
Prevention:
Store IDs immediately when created
Validate IDs before polling
Check session status first
Handle 404 errors gracefully
CAPTCHA & Security Challenges
CAPTCHA Blocking Tasks
Symptoms:
Tasks fail at CAPTCHA pages
Agent cannot proceed past security checks
Guardrail triggers asking how to handle CAPTCHA
Common Causes:
Website uses bot detection
High security on target site
Rate limiting triggered CAPTCHA
IP address flagged
Solutions:
Manual Intervention via Guardrails
// When CAPTCHA is encountered, guardrail will trigger
ws . onmessage = async ( event ) => {
const data = JSON . parse ( event . data );
if ( data . type === "guardrail_trigger" ) {
if ( data . data . value . includes ( "CAPTCHA" ) || data . data . value . includes ( "verification" )) {
// Notify user to solve CAPTCHA
console . log ( "CAPTCHA detected - manual intervention required" );
// User solves CAPTCHA in browser stream
const userConfirmation = await askUser ( "Have you solved the CAPTCHA?" );
// Resume task
await fetch ( "https://connect.webrun.ai/start/send-message" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
message: {
actionType: "guardrail" ,
prompt: "CAPTCHA solved, continue" ,
newState: "resume"
}
})
});
}
}
};
Use Manual Takeover
// Switch to manual control for CAPTCHA
await fetch ( "https://connect.webrun.ai/start/send-message" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
message: { actionType: "state" , newState: "manual" }
})
});
// User solves CAPTCHA via stream
// Return to agent control
await fetch ( "https://connect.webrun.ai/start/send-message" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
sessionId ,
message: { actionType: "state" , newState: "resume" }
})
});
Avoid CAPTCHA-Heavy Sites
// Add known CAPTCHA-heavy domains to avoid list
const session = await fetch ( "https://connect.webrun.ai/start/start-session" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ apiKey } `
},
body: JSON . stringify ({
prompt: "Research products"
})
});
Rate Limit Your Requests
// Avoid triggering rate-limit CAPTCHAs
async function rateLimitedTasks ( tasks , delayMs = 5000 ) {
const results = [];
for ( const task of tasks ) {
const result = await executeTask ( task );
results . push ( result );
// Wait between tasks
if ( tasks . indexOf ( task ) < tasks . length - 1 ) {
await new Promise ( r => setTimeout ( r , delayMs ));
}
}
return results ;
}
Prevention:
Use manual takeover mode when CAPTCHAs expected
Rate limit requests to avoid triggering security
Test target sites beforehand
Have fallback strategy for CAPTCHA sites
Debugging Tips
Enable Verbose Logging
class WebRunClient {
constructor ( apiKey , debug = false ) {
this . apiKey = apiKey ;
this . debug = debug ;
}
async request ( url , options ) {
if ( this . debug ) {
console . log ( `[DEBUG] Request to ${ url } ` );
console . log ( `[DEBUG] Options:` , JSON . stringify ( options , null , 2 ));
}
const response = await fetch ( url , {
... options ,
headers: {
... options . headers ,
"Authorization" : `Bearer ${ this . apiKey } `
}
});
const data = await response . json ();
if ( this . debug ) {
console . log ( `[DEBUG] Response:` , JSON . stringify ( data , null , 2 ));
}
return { response , data };
}
}
// Usage
const client = new WebRunClient ( apiKey , true ); // Enable debug mode
Monitor All Events
function monitorAllEvents ( sessionId , apiKey ) {
const ws = new WebSocket (
`wss://connect.webrun.ai/ws?sessionId= ${ sessionId } &apiKey= ${ apiKey } `
);
ws . onmessage = ( event ) => {
const data = JSON . parse ( event . data );
console . log ( `[EVENT] ${ data . type } :` , data );
// Log specific event types
switch ( data . type ) {
case "task_started" :
console . log ( "Task started:" , data . data . taskId );
break ;
case "task_completed" :
console . log ( "Task completed with usage:" , data . data . usage );
break ;
case "guardrail_trigger" :
console . log ( "Guardrail triggered:" , data . data . value );
break ;
case "error" :
console . error ( "Error occurred:" , data . data );
break ;
}
};
}
Quick Reference
Issue First Thing to Try Documentation Session pending too long Wait 30s, then terminate & recreate Sessions Task timeout Increase maxDuration or simplify task Tasks High costs Set maxInputTokens and maxOutputTokens Cost Optimization Guardrails firing Make instructions more specific Guardrails Stream not loading Verify session is active Streaming WebSocket failing Implement polling fallback Events CAPTCHA blocking Use manual takeover mode Manual Control
Next Steps
Error Codes Reference Complete list of error codes
FAQs Frequently asked questions
Best Practices Guidelines for optimal usage
Get Support Contact our support team