Skip to main content

Overview

Nen executes your Python code in a secure, sandboxed environment while allowing you to debug locally. This page explains the execution model and debugging strategies.

Remote Python Execution Model

When you trigger a workflow:
  1. Your code uploads to Nen’s secure infrastructure
  2. Sandbox launches in an isolated Chainguard container
  3. Python executes with access to the Nen SDK
  4. SDK calls communicate with the desktop via the agent engine
Your code runs in a containerized environment—no need to install Python or dependencies locally.

Local Development with VSCode

For development, you can run Python locally while connecting to a remote desktop:

Setup

  1. Install the Nen SDK locally:
    uv init && uv add nen
    
  2. Configure your environment:
    export NEN_API_KEY="your_api_key"
    export NEN_DEPLOYMENT_ID="deploy_abc123"
    
  3. Run your workflow:
    python workflow.py
    
Use VSCode’s debugger to set breakpoints, inspect variables, and step through your code while it controls the remote desktop.

Error Handling

Transient vs Fatal Errors

Error TypeDescriptionAction
TransientTemporary issues (network, timeout)Retry automatically
FatalPermanent failures (auth, not found)Stop and report

Using try/except/finally

Handle errors gracefully in your workflows:
from nen import Agent, WorkflowError, RPCError
from pydantic import BaseModel

class Params(BaseModel):
    ...

class Result(BaseModel):
    ...

def run(params: Params) -> Result:
    agent = Agent()
    try:
        agent.execute("Navigate to the reports section")
        agent.verify("Is the reports page visible?", timeout=15)

    except RPCError as e:
        # Communication issue—could retry
        print(f"RPC error: {e}")
        raise  # Let Nen retry

    except WorkflowError as e:
        # Permanent failure—stop execution
        print(f"Workflow error: {e}")
        raise

    finally:
        # Always runs—cleanup
        print("Workflow execution complete")

Common Errors

ErrorTypeResolution
VerificationTimeoutFatalIncrease timeout or check screen state
ConnectionLostTransientAuto-retry, check network
ElementNotFoundFatalVerify element exists, refine instruction
AuthenticationFailedFatalCheck credentials

Debugging Tips

1. Use Verbose Logging

Add print statements to trace execution:
def run(params: Params) -> Result:
    agent = Agent()
    print(f"Step 1: Navigating to {params.url}")
    agent.execute(f"Go to {params.url}")
    print("Step 1: Complete")

2. Check Screenshots

Each SDK call captures a screenshot. Review them in the run details to see what the AI observed.

3. Simplify and Isolate

Test individual steps before combining:
def run(params: Params) -> Result:
    agent = Agent()
    # Test just this step
    agent.execute("Click the login button")
    # Comment out the rest until this works

4. Increase Timeouts

Slow applications may need longer waits:
def run(params: Params) -> Result:
    agent = Agent()
    agent.verify("Is the page loaded?", timeout=30)  # 30 seconds

Next Steps

Multiple Workflows

Managing stateful desktop environments

Observability

Logs, screenshots, and recordings