Troubleshooting
Debug AI Requests
When a request fails or behaves unexpectedly, match what your application saw to what the gateway decided. The link between the two is the request ID. Start with one failed request, and keep its HTTP status, response body, X-Request-Id, and approximate time.
1. Examine the client response
Read the error.code, not just the message; Error Handling tells a policy block apart from a credential problem, a spend limit, or a provider failure.
Also check that the request went to your Verdictan gateway or agent URL. Requests sent straight to a provider never appear in Verdictan.
2. Read events while you reproduce the problem
Send the request again. Then, signed in with an account that has events:read in the right organization and region, read the recent events:
verdictan events tail --since 10m --jsonFind the decision event for your request. The command reads events delivered to Verdictan, not local logs. Delivery is asynchronous, so the event can arrive shortly after the response. If it is not there yet, run the command again.
3. Match the request
Event request IDs are normalized, so they may not look like the X-Request-Id you received:
- A 32-character lowercase hexadecimal ID is kept as is.
- A UUID loses its hyphens.
- Any other value becomes a derived identifier. The conversion snippet computes it.
With the normalized ID, query the events API. Use an account API token, not the application token:
export VERDICTAN_API_URL="https://api.eu.verdictan.com"
REQUEST_ID="replace-with-the-normalized-request-id"
curl --fail-with-body --silent --show-error --get \
--header "Authorization: Bearer $VERDICTAN_API_TOKEN" \
--data-urlencode "since=24h" \
--data-urlencode "request_id=$REQUEST_ID" \
"$VERDICTAN_API_URL/v1/events"For a US organization, use https://api.us.verdictan.com. From the matching event, read verdict, reason_code, config_version, provider, and model, and compare them with what you expected.
4. Add context if necessary
| To see | Look in |
|---|---|
| The saved prompt and response | History, if capture was on |
| Configuration changes | Trail, and the configuration's version history |
| Human review status | Inbox |
| Gateway connection status | Gateways, and the gateway's local logs |
A missing record doesn't prove a request never happened. Capture settings, retention, delivery, permissions, and request-family support all limit what is recorded.
A policy blocks a request unexpectedly
- Read the event's
reason_codeto see which control decided. - Check
config_versionagainst the active configuration. If it changed recently, look at that change in Trail. - Follow Investigate a Blocked Request to read the evidence before you change a rule.
- Reproduce the prompt as a case in
verdictan policy test, change the rule, and check that the case gets the verdict you want.
Verify the correction
After the fix, send one new request, check the application result, and find its event. The decision should match what you expect. Keep the new request ID with the original report.
Troubleshooting
| Symptom | Next check |
|---|---|
| Slow response | Compare nearby requests and gateway health. An output control may hold the whole answer before sending it. |
| Human review | Open the linked Inbox item. Approving it does not replay the request. |
| No event | Organization, region, time window, gateway connection, and request-family support. |
| No History content | Capture and retention settings. Use the decision event instead. |
Next steps
- Error Handling: what each status and code means for your application.
- Troubleshooting: gateway start and connection problems.