Read execution logs and diagnose errors
By the end of this lesson, you can read execution logs to diagnose tool-call problems.
Execution records and messages
Section titled “Execution records and messages”The execution log shows which tools ran, what they returned, and whether the run completed. Use it to investigate incorrect answers, slow responses, and errors. This lesson reads the run from lesson 3.
Read the execution log
Section titled “Read the execution log”UC AI records two things for each run:
uc_ai_agent_executionsholds one row per run, with the caller, status, token counts, and run context.uc_ai_agent_messagesholds one row for each message item, in order. This includes a row for each tool call and each tool result.
Both tables include the session ID. Lesson 3 printed it after SESSION:.
In SQLcl, run variable session_id varchar2(255). Then run
execute :session_id := 'PASTE_SESSION_ID_HERE', with your ID in place of the
placeholder. The queries below use this bind variable.
If you did not keep the ID, read session_id from the latest execution record
for SC_DESK in uc_ai_agent_executions.
Read the messages of the lesson 3 run:
select seq , role , tool_name , substr(coalesce(tool_input, content), 1, 60) as detail from uc_ai_agent_messages where session_id = :session_id order by seq;SEQ ROLE TOOL_NAME DETAIL1 user - How much can I still credit on INV-1003, and is the call ins2 reasoning -3 tool_call SC_GET_CONTRACT {}4 tool_call SC_LIST_INVOICES {"max_rows":20}5 tool_call SC_LIST_CALLS {"max_rows":20}6 tool_result SC_GET_CONTRACT7 tool_result SC_LIST_INVOICES8 tool_result SC_LIST_CALLS9 assistant - INV-1003 has **€0** left to credit; its full €200 has alreadThe recorded trace shows:
- The model asked for three tools in one round (
seq3 to 5), then read all three results. A round can hold more than one call. - The arguments were
{}and{"max_rows":20}. There is no contract in them, because no tool declares one.tool_inputis what the model sent, and UC AI adds_ctxafter that point. The next query reads the run context from the execution row. - The answer at
seq9 came after the results at 6 to 8.
Read recent execution details
Section titled “Read recent execution details”Run this query to read the five most recent executions of SC_DESK:
select e.id as execution_id , e.status , e.created_by , e.audience , e.tool_calls_count , e.total_input_tokens , e.total_output_tokens , e.run_context , e.error_message from uc_ai_agent_executions e where e.agent_id = ( select id from uc_ai_agents where code = 'SC_DESK' ) order by e.started_at desc fetch first 5 rows only;Selected columns from the lesson 3 execution:
STATUS CREATED_BY AUDIENCE TOOL_CALLS_COUNT IN OUT RUN_CONTEXTcompleted UC_AI db 3 1854 172 {"contract_id":"88"}run_context records the contract ID supplied by the application.
Diagnose tool-call problems
Section titled “Diagnose tool-call problems”The model called no tool
Section titled “The model called no tool”If the trace contains no tool_call row, inspect the profile configuration,
tool tags, and descriptions:
-
The tag did not reach the profile. Read it back:
select model_config_json from uc_ai_prompt_profileswhere code = 'SC_DESK_PROFILE' and version = 1;You must see
"g_enable_tools": trueand your tag in"g_tool_tags". Lesson 3 wrote both. -
The tag matches no active tool. A tag with no tool behind it gives the model nothing, and no error:
select t.code, t.active, g.tagfrom uc_ai_tools t join uc_ai_tool_tags g on g.tool_id = t.idwhere g.tag = 'scdesk'; -
The description does not say when to use the tool. The description must explain both the returned data and when to request it. For example: “List invoice amounts and existing credits. Use this before you raise a credit note.”
The tool ran and the model ignored it
Section titled “The tool ran and the model ignored it”The trace contains a tool_call and a tool_result, but the answer does not
use the returned data.
Read tool_output to see what the handler returned:
select seq, tool_name, substr(tool_output, 1, 200) as tool_output from uc_ai_agent_messages where session_id = :session_id and role = 'tool_result' order by seq;One possible cause is a handler refusal. The demo handlers return
"status":"refused" and a reason when they cannot process a request. The model
can report that refusal instead of the requested invoice data.
The run stopped early
Section titled “The run stopped early”g_max_tool_calls sets a stopping threshold for the tool loop. To read the
actual number of requested calls, run this query:
select count(*) as tool_calls from uc_ai_agent_messages where session_id = :session_id and role = 'tool_call';What a failed run records
Section titled “What a failed run records”On a failed execution record, the token and tool-call counts remain 0.
The framework has no result object from which to read the totals.
Run this query to inspect failed execution records:
select status, error_message, total_input_tokens, tool_calls_count from uc_ai_agent_executions where status = 'failed' order by started_at desc fetch first 3 rows only;So tool_calls_count = 0 on a failed row does not mean “no tool ran”. Count the
tool_call rows in uc_ai_agent_messages instead. On a completed row, the
column records the tool-call count.
Verification
Section titled “Verification”Run the recent-executions query for your lesson 3 run. Inspect these columns:
run_contextholds{"contract_id":"88"}. A missing contract ID causes the demo handlers to refuse requests.tool_calls_countmatches the number oftool_callrows in the trace. The recorded run has3in both places. Your model can ask for two or three.
Key takeaways
Section titled “Key takeaways”- Use execution records and messages to diagnose a run.
- Read
tool_outputto distinguish a handler refusal from returned invoice data. select seq, role, tool_name, tool_input from uc_ai_agent_messages where session_id = :s order by seq;
Full reference: Conversation message log has every column and the attribution rules for multi-agent patterns.