Skip to main content

Error Handling

You Can't Break The Agent

Any unhandled exception in your tool is automatically caught by the agent. It will never crash the process. The error is captured, sent to NINA as a failure event, and the agent continues processing the next message. You don't need try/catch around everything — just write your tool logic and let it fail naturally if something goes wrong.

Exit Codes

CodeStatusMeaning
0SuccessTool completed, output uploaded to S3
1FailureTool failed, error reported to NINA
-1TimeoutTool exceeded timeout, error reported to NINA

Handling Errors in Your Tools

Fail Fast (Workflow Stops)

Raise an exception when the error is critical:

@beam_tool(name="strict_scanner")
async def strict_scanner(input_paths, output_path, parameters):
if not parameters.get('target'):
raise ValueError("Parameter 'target' is required")

return await scan(parameters['target'])

Graceful Degradation (Workflow Continues)

Return error info as output when the workflow should continue:

@beam_tool(name="best_effort_scanner")
async def best_effort_scanner(input_paths, output_path, parameters):
try:
result = await scan(parameters['target'])
return {"status": "success", "data": result}
except Exception as e:
return {"status": "error", "message": str(e)}

What Happens on Failure

  1. Agent sends a execution.phase.failed completion event to NINA
  2. Message is deleted from the queue (no automatic requeue)
  3. NINA marks the node as failed

Exception: If the agent process crashes (killed, machine reboots), the message reappears in the queue after the visibility timeout and will be retried. Make sure your tools are safe to re-execute.

Next Steps