Troubleshooting
Enable SDK debug logs before reproducing an issue:
export STASO_DEBUG=1No new traces appear
- Confirm
STASO_API_KEYandSTASO_AGENT_NAMEare set, or pass both tost.init. - Confirm
enabled=Falseis not set. - Check debug output for an ingestion response.
- Verify outbound HTTPS access to
https://api.staso.ai. - Confirm the organization plan and API key scope in the dashboard.
Trace delivery does not normally fail the application call. When delivery is required, inspect the DeliveryReport returned by st.flush() or st.shutdown(). A false report.ok and its last_failure, rejected, and last_rejection fields distinguish remote delivery failure, pending work, timeout, and local queue rejection.
Native provider calls are not observed
Install the provider-specific extra and initialize Staso before constructing the provider client:
pip install "staso[openai]"
# or: pip install "staso[anthropic]"The supported provider paths are OpenAI Chat Completions and Anthropic Messages, sync or async and non-streaming. Wrap the agent entry point with @st.agent, and wrap actual Python tool execution with @st.tool.
Launch setup health looks stale
For the pinned launch sample, DeliveryReport.ok means the SDK reached ingest acceptance. It is not the final evidence that the dashboard can query the trace. Wait for the selected workspace to return the trace with the expected session_id, environment, provider LLM span, and decorated tool span.
Setup health uses these boundaries:
| Field or category | Meaning |
|---|---|
connection_status=connected | The selected workspace has a query-visible trace. |
last_successful_ingestion_at | Query-visible ingestion time for the latest stored trace, not client time. |
provider_patch_status=observed | A stored kind=llm span contains provider=openai or provider=anthropic. |
invalid_key | Replace the key and restart the process. |
forbidden | Check workspace scope, traces:write, and guard:evaluate when Guard is configured. |
plan_expired | Fix the account plan or contact [email protected]. |
rate_limited | Check usage and retry after the limit window. |
backend_unavailable, network_unavailable, timeout | Retry after the service or network recovers. |
malformed_response, queue_full, shutdown, disabled | Use the safe category for debugging; do not send secrets, prompts, tool arguments, provider responses, or customer data to support. |
Guard returns allow when no decision is available
Guard fails open by default, so authentication, service, response, or deadline failures return an explicit unavailable result without crashing the application. To fail closed for a direct check:
result = st.guard("shell", {"cmd": "dangerous-command"}, fail_closed=True)Or configure it globally:
export STASO_GUARD_FAIL_CLOSED=trueSee manual Guard checks.
Ingestion returns 401, 403, or 429
401means authentication was rejected. Check whether the key was replaced, revoked, or expired, then restart long-lived processes after updating it.403means the key lackstraces:write, the organization/workspace is disabled, or an explicit workspace slug is outside a workspace-scoped key's allowed set.429means a current service limit was reached. HonorRetry-Afterwhen provided.
Guard evaluation separately requires guard:evaluate. Its stable unavailable reason distinguishes authentication rejection, capability/tenant rejection, rate limiting, and other service unavailability without copying backend response text into application logs.
Capture is still present
For the Python API, explicit category arguments override category environment variables; capture_messages is only a deprecated fallback for request and system_prompt. The CLI-agent beta pages describe how to inspect their persisted category matrix.
Suppression removes governed values from SDK payloads. It is distinct from backend redaction of enabled content. If a tool-call argument appears inside assistant output, both tool_arguments and output must be enabled for it to be sent.