Skip to main content

Common Errors

SDK Errors

PolicyViolationError

waxell_observe.errors.PolicyViolationError: Policy check returned action=block: Budget limit exceeded for agent 'my-agent'

What it means: A governance policy blocked your agent from running. This can happen at:

  • Pre-execution (on context entry or decorator invocation): The agent was blocked before any code ran.
  • Mid-execution (during record_step() with mid_execution_governance=True): The agent was blocked while running.

How to fix:

  1. Check the policy result for details:

    try:
    result = await my_agent(query)
    except PolicyViolationError as e:
    print(e.policy_result.action) # "block" or "throttle"
    print(e.policy_result.reason) # Human-readable explanation
    print(e.policy_result.metadata) # Additional context
  2. Review your policies in the Waxell dashboard under Governance > Policies.

  3. To skip policy checks during development:

    @waxell.observe(agent_name="my-agent", enforce_policy=False)
  4. To add an approval workflow instead of hard blocking:

    @waxell.observe(
    agent_name="my-agent",
    on_policy_block=waxell.prompt_approval,
    )

ConfigurationError

waxell_observe.errors.ConfigurationError: WaxellObserveClient is not configured. Call configure() or pass api_url and api_key.

What it means: The SDK tried to make an API call but has no credentials configured.

How to fix:

Option 1 -- Use init() (recommended):

import waxell_observe as waxell
waxell.init(api_key="wax_sk_...", api_url="https://acme.waxell.dev")

Option 2 -- Environment variables:

export WAXELL_API_URL="https://acme.waxell.dev"
export WAXELL_API_KEY="wax_sk_..."

Option 3 -- CLI config file (~/.waxell/config):

[default]
api_url = https://acme.waxell.dev
api_key = wax_sk_...

Option 4 -- Direct client configuration:

from waxell_observe import WaxellObserveClient
WaxellObserveClient.configure(api_url="https://acme.waxell.dev", api_key="wax_sk_...")

PromptNotFoundError

waxell_observe.errors.PromptNotFoundError: Prompt 'summarizer' not found (label='production', version=0)

What it means: The SDK tried to fetch a prompt from the control plane prompt registry, but it doesn't exist or the specified label/version isn't available.

How to fix:

  1. Check the prompt name and label in the Waxell dashboard under Prompts.
  2. Ensure the prompt has been published with the label you're requesting:
    # Fetch by label
    prompt = await client.get_prompt("summarizer", label="production")

    # Fetch latest version (no label needed)
    prompt = await client.get_prompt("summarizer")
  3. If the prompt was recently created, the SDK caches prompt lookups for 60 seconds. Wait or restart your application.

PromptGuardError

waxell_observe.errors.PromptGuardError: Prompt guard detected violations: [PII: email address found]

What it means: The Prompt Guard feature detected sensitive content (PII, credentials, or injection attempts) in an LLM input and the guard action is set to "block".

How to fix:

  1. Review the detected violations:

    try:
    response = await client.chat.completions.create(...)
    except PromptGuardError as e:
    print(e) # Shows violation details
  2. Change the guard action to "warn" (log and continue) or "redact" (replace with placeholders):

    waxell.init(prompt_guard=True, prompt_guard_action="redact")
  3. To disable prompt guard entirely:

    waxell.init(prompt_guard=False)

ObserveError

waxell_observe.errors.ObserveError: ...

What it means: Base error class for all Waxell Observe errors. If you catch ObserveError, you catch all SDK-specific errors.

from waxell_observe.errors import ObserveError

try:
result = await my_agent(query)
except ObserveError as e:
# Catches PolicyViolationError, ConfigurationError, PromptNotFoundError, etc.
print(f"Waxell error: {e}")

Runtime Warnings

"waxell-observe not configured, skipping run"

WARNING waxell_observe - Client not configured, skipping run start for 'my-agent'

What it means: The SDK has no API credentials configured. The @observe decorator or WaxellContext ran your function normally but didn't create a run on the control plane.

How to fix: Configure credentials via init(), environment variables, or ~/.waxell/config. See ConfigurationError above.


"Failed to start run" / "Failed to complete run"

WARNING waxell_observe - Failed to start run for 'my-agent': ConnectionError
WARNING waxell_observe - Failed to complete run abc-123: TimeoutError

What it means: The SDK couldn't reach the control plane API. Your agent code executed normally -- the warning is about telemetry loss only.

How to fix:

  1. Check your network connectivity to the control plane URL.
  2. Verify the api_url is correct (should be https://<tenant>.waxell.dev).
  3. Enable debug mode for more details: waxell.init(debug=True).
  4. These warnings are expected if you're running offline or in an environment without control plane access.

"OTel tracing initialization failed"

WARNING waxell_observe - OTel tracing initialization failed: ModuleNotFoundError: No module named 'opentelemetry'

What it means: The OpenTelemetry packages are not installed. The SDK falls back to HTTP-only telemetry (which works fine for most use cases).

How to fix: If you need OTel spans (e.g., for Grafana, Jaeger, or Datadog):

pip install waxell-observe[otel]

If you don't need distributed tracing, this warning is safe to ignore.


"Sync wrapper using ThreadPoolExecutor"

WARNING waxell_observe - Running sync function in ThreadPoolExecutor (event loop already running)

What it means: You decorated a sync function with @observe and called it from inside an async event loop (e.g., Jupyter notebook, FastAPI, uvicorn). The decorator falls back to a thread pool to avoid blocking.

How to fix: Make the decorated function async:

# Before (triggers warning in async contexts)
@waxell.observe(agent_name="my-agent")
def my_sync_function(query: str):
return process(query)

# After (no warning)
@waxell.observe(agent_name="my-agent")
async def my_async_function(query: str):
return await process(query)

Import Errors

"waxell-observe core modules are not available for this platform"

ImportError: waxell-observe core modules are not available for this platform.
Install a pre-built wheel: pip install --only-binary=waxell-observe waxell-observe

What it means: The package was installed from source but a compiled module failed to build.

How to fix:

pip install --only-binary=waxell-observe waxell-observe

"No module named 'waxell_observe'"

ModuleNotFoundError: No module named 'waxell_observe'

How to fix:

pip install waxell-observe

Make sure you're installing in the correct virtual environment:

which python          # Check active environment
pip install waxell-observe
python -c "import waxell_observe; print(waxell_observe.__version__)"

Debugging Tips

Enable debug mode

Debug mode enables verbose logging and console span export:

waxell.init(debug=True)

Or via environment variable:

WAXELL_DEBUG=true python my_agent.py

Use diagnose() to check SDK state

import waxell_observe as waxell
waxell.init()

info = waxell.diagnose()
print(info)
# {
# "sdk_version": "0.0.40",
# "initialized": True,
# "active_instrumentors": ["openai", "anthropic"],
# "detected_libraries": {"openai": "1.52.0", "anthropic": "0.40.0"},
# "config": {"api_url": "https://acme.waxell.dev", "api_key_set": True},
# "tracing": {"enabled": True, "provider": "WaxellTracerProvider"},
# }

Check if a context is active

ctx = waxell.get_context()
if ctx:
print(f"Active run: {ctx.run_id}")
else:
print("No active context -- convenience functions are no-ops")