Skip to main content
Agentic applications interact with unreliable dependencies (LLMs, tools, external APIs). This guide explains how errors propagate in Tensorlake Applications and common patterns for building resilient workflows on the Agentic Runtime.

How failures propagate

  • A function can fail by raising an exception or timing out.
  • If an exception is not handled, it bubbles up to the caller and can fail the overall request.
  • Retries can be configured per-function or at the application level. See Retries.

Pattern: catch errors and continue

Use try/except inside your application to decide whether to fail the request or degrade gracefully.
from tensorlake.applications import application, function

@function()
def call_tool(x: str) -> str:
    # e.g., LLM/tool/API call that can fail
    raise RuntimeError("tool failed")

@application()
@function()
def workflow(user_input: str) -> dict:
    try:
        tool_output = call_tool(user_input)
        return {"status": "ok", "tool_output": tool_output}
    except Exception as e:
        # Decide how your agent/workflow should behave on failure
        return {"status": "degraded", "error": str(e)}

Pattern: retries for flaky dependencies

Retries are a good fit for transient failures (timeouts, 429s, temporary upstream errors). Configure them on the function (or set defaults on the application).
from tensorlake.applications import function, Retries

@function(retries=Retries(max_retries=3))
def flaky_step() -> str:
    ...

Futures: handling parallel failures

When using Futures, errors are raised when you call .result():
from tensorlake.applications import application, function, Future

@function()
def maybe_fails() -> str:
    raise RuntimeError("boom")

@application()
@function()
def parallel_work() -> str:
    fut: Future = maybe_fails.awaitable().run()
    try:
        return fut.result()
    except Exception as e:
        return f"handled: {e}"

Debugging tips

  • Start by reproducing locally: Tensorlake Applications run as normal Python functions locally. See Testing locally.
  • Add structured logs: log inputs/outputs (excluding secrets) so you can diagnose failures.
  • Make side effects idempotent: if a function can retry, avoid double-charging or double-writing.