Your Agent emits a tool call, but the task still ends with an empty answer, a validation error, or an action that ran only once.
Fastest fix: do not change the model or widen permissions first. Reproduce the failure across five layers: tool definition, call request, execution result, session state, and retry or rollback behavior.
This guide is for developers who have completed an OpenAI Agents API Quickstart but see unstable tool results, engineers adding function calling or MCP to a production Agent, and platform owners who need durable logs and recovery rules for cloud AI Agent workloads.
Start with a failure timeline, not a new model
The phrase “tool calling failed” hides several different defects. A model may never request a tool. It may request one with invalid arguments. Your executor may reject a valid request. The business API may fail after execution begins. Or the tool may succeed while its result never reaches the next Agent turn.
Do not classify the incident from the final answer alone. A wrong final answer can result from:
- No tool call being emitted.
- A tool call using the wrong name or malformed arguments.
- A valid call reaching an unavailable or unauthorized service.
- A successful operation returning data in a format the Agent cannot use.
- A result being written to the wrong session, turn, or application state.
- A side effect succeeding before a later step fails.
The official function calling guide describes the model-to-application handoff. Your debugging record should mirror that handoff. Preserve the request sent to the model, the raw response containing the tool call, the executor input, the executor output, and the next Agent response. Redact tokens, personal data, and business secrets before storing the record.
A useful event record includes:
- A correlation ID shared by the user task, Agent run, tool call, and business request.
- The exact tool name and schema version.
- Raw model arguments before application-side conversion.
- Validation output, including the rejected field and expected type.
- Executor start and finish timestamps.
- External API status, response body, and timeout category.
- The session, turn, and item identifiers used for the result handoff.
- Whether the operation created a side effect.
- The recovery decision and the person or system that approved it.
This timeline tells you where to look next. It also prevents an operator from retrying a payment, deletion, or deployment simply because the final Agent message looks incomplete.
Step one: lock the tool contract before testing behavior
A tool definition is an execution contract, not just a prompt hint. Check the name, description, input object, required fields, enum values, nested objects, and return shape against the actual executor. The OpenAI tool calling documentation is the baseline for how your application should receive arguments and return tool output.
Run a fixed test set before using free-form user prompts. Include:
- A complete valid object.
- A missing required field.
- An unexpected enum value.
- A string where the executor expects a number or boolean.
- An explicit null value.
- An empty array or empty nested object.
- A value with extra whitespace or a different case.
- A valid request that the downstream business API must reject.
The point is not to make the model “guess better.” The point is to identify whether your boundary accepts the same data that your schema advertises.
Match validation, conversion, and business rules
A frequent defect appears when three layers disagree:
- The schema says a field is optional.
- The application converts an absent field into null.
- The business API requires a non-empty value.
Another occurs when a schema permits several enum values but the executor implements only one. A third occurs when a nested object is accepted by the validator but flattened by a conversion helper before dispatch.
Keep these rules explicit. Validate raw arguments first. Convert types in one named function. Apply business validation after conversion. Return a structured error that identifies whether the problem is malformed input, authorization, unavailable service, or a rejected business operation.
If you use MCP tools or connectors, apply the same discipline to the remote tool boundary. The MCP and connector guidance should define what the tool exposes, while your application still needs to record the selected tool, arguments, permission decision, and returned data.
Step two: isolate the four failure classes in a single-tool run
Before testing a long task, disable every optional tool and run one deterministic function. Keep the user input fixed. The goal is to distinguish four observable states.
| Observed state | Verification action | Likely fault | Recovery action |
|---|---|---|---|
| No tool call appears | Inspect the raw model response and tool list | Tool selection, registration, or prompt context | Verify registration, description, availability, and requested behavior |
| Tool call appears with invalid arguments | Validate raw arguments against the schema | Schema, conversion, or model output mismatch | Fix the contract and reject safely before execution |
| Arguments are valid but execution fails | Replay the executor with the same inputs | Network, credentials, rate limit, timeout, or business rule | Classify the error and apply a bounded recovery policy |
| Execution succeeds but Agent stops or misreads it | Compare tool output with the next turn input | Result handoff, state association, or output format defect | Attach the result to the correct run state and continue explicitly |
This table is a decision tool: it tells you which component to change without guessing. For example, adding a larger model cannot repair a missing result handoff. Expanding permissions cannot repair a malformed enum. Repeating a request cannot repair an executor that has already created a side effect.
Verify the raw call before your framework normalizes it
Framework wrappers often make logs easier to read but can hide the original failure. Log the unmodified tool name and argument payload at the boundary where your application receives them. Then log the normalized executor input separately.
If the raw call is correct but the normalized input is wrong, the defect is local to your adapter. If the raw call is already wrong, inspect the schema and the model-visible tool description. If the raw call is absent, inspect tool registration and the Agent instructions before inspecting the business API.
Never log credentials embedded in headers, environment variables, MCP configuration, or tool arguments. A debugging trace that exposes a secret is a security incident, not a successful diagnostic.
Step three: test result handoff as a separate operation
A function can execute correctly while the Agent still behaves as if nothing happened. Treat the result handoff as its own test.
Return a small, deterministic payload first. Include an explicit outcome field, a human-readable summary, and structured data that the next step needs. Avoid returning a large unbounded document while you are testing state propagation. Large outputs can create truncation, serialization, or parsing problems that obscure the original issue.
Check these boundaries in order:
- Did the executor finish?
- Did it return a serializable value?
- Did the application associate the result with the original tool call?
- Did the result enter the expected Agent turn or session?
- Did the next model response receive the result rather than only the original user message?
- Did your application accidentally replace the result with an empty string, exception message, or unrelated state?
The Agents API supports tools and session-oriented execution patterns, but the application still has to preserve the correct state across its own request boundaries. Use the Agents API documentation on tools, sessions, and environments as the platform boundary, then document your own state mapping.
A practical test is to make the tool return a unique marker such as a generated task reference. The next Agent step must quote or transform that marker. If the executor log contains it but the next response does not, the problem is almost certainly in result propagation, session selection, or turn construction.
Step four: compare dependent and parallel tool calls
Only enable multi-step behavior after the single-tool path is stable. Use two test shapes:
- Two independent tools that can run without each other.
- Two dependent tools where the second requires a value produced by the first.
The independent case tests whether parallel dispatch, result collection, and ordering work. The dependent case tests whether the application waits for the prerequisite result and passes it into the next step.
Do not infer dependency from tool names. Declare it in application logic or task state. A model may request multiple calls that appear related, but your executor must still protect operations that require a confirmed output from an earlier step.
Common multi-step defects include:
- Starting a dependent call before its input exists.
- Returning parallel results in an order the Agent does not expect.
- Saving the first result in process memory while the next turn reads a database record.
- Mixing an Agents API session with an application conversation ID.
- Reusing a stale turn after a timeout.
- Marking a step complete before the external side effect is confirmed.
Keep state ownership clear:
| State item | Owner | Must survive what event? | Verification record |
|---|---|---|---|
| Tool schema and version | Application deployment | Process restart and rollout | Schema hash or release ID |
| Agent session and turn reference | Agent integration layer | Request retry and worker handoff | Session, turn, and item identifiers |
| Business operation status | Business service | Agent timeout or model retry | Idempotency key and operation state |
| Approval decision | Control layer | Worker restart and audit review | Approver, timestamp, scope, and decision |
| Recovery checkpoint | Orchestrator | Partial task failure | Completed step, pending step, and compensation plan |
This separation matters because an Agent session is not automatically the same thing as your order, deployment, ticket, or workflow record. Store the business state where the business system can enforce it. Store Agent execution references where the integration layer can resume the run.
Step five: add retries only after classifying the error
A retry policy should answer three questions before it sends another request:
- Did the operation start?
- Could repeating it create a harmful side effect?
- Can the same request be identified and safely deduplicated?
Transient transport failures, temporary service unavailability, and bounded timeouts may be retryable. Invalid arguments, missing permissions, rejected business rules, and unsupported tool names usually are not. A payment, deletion, external publication, infrastructure change, or data mutation requires extra protection even when the transport error looks temporary.
Use an idempotency key derived from the business operation, not from a newly generated retry attempt. Record the key with the external system when possible. If the external system cannot provide idempotency, use a local operation record and query the result before replaying the action.
For destructive or externally visible tools, introduce an approval boundary. The Guardrails and approvals guidance covers the role of approval and human review in Agent workflows. Your implementation should also define what happens when approval expires, is denied, or arrives after the original session has timed out.
A recovery policy should include:
- A bounded retry decision.
- A timeout budget for each external call.
- A maximum amount of work that can be replayed.
- A human takeover condition.
- A compensation action where the original side effect cannot be undone.
- A final state that distinguishes failed, pending, completed, and unknown.
“Unknown” is essential. If the network fails after the external service accepts a request, you may not know whether the action happened. Treating unknown as failed and blindly retrying can duplicate the side effect.
Step six: build long-term observability around the timeline
Once the single-tool and multi-step tests pass, move the same event structure into production logging. The Agents observability documentation provides the reference point for tracing Agent activity. Your platform should connect that trace to application logs and external API records.
Track failures by layer rather than by final user message:
- Tool selection failures.
- Schema validation failures.
- Executor failures.
- Permission and credential failures.
- External service timeouts.
- Result serialization failures.
- Session or turn association failures.
- Approval timeouts.
- Unknown side-effect outcomes.
Create an alert for a sudden change in any one layer. A rising executor timeout rate needs a different response from a rising schema rejection rate. Likewise, a growing number of unknown outcomes requires a side-effect review, not a prompt revision.
If your Agent runs in a hosted environment, verify network access, credential injection, filesystem assumptions, and process lifetime separately. The official environment and security guidance defines important boundaries, but your acceptance test must still exercise the actual APIs and permissions used by your workload.
Keep a small replay suite in version control. It should contain sanitized requests for valid calls, invalid arguments, unavailable dependencies, approval-required actions, partial completion, and duplicate retry attempts. Run it after changing schemas, tools, SDK versions, session handling, or security policies.
Use this recovery matrix before promoting the Agent
The following matrix turns a vague “unstable tool call” report into an operational decision. It is intentionally conservative around side effects.
| Failure condition | Retry automatically? | Required protection | Escalate when |
|---|---|---|---|
| Tool is missing or not registered | No | Deployment and schema check | Registration differs from the expected release |
| Arguments fail validation | No | Return a structured validation error | The same field fails across valid test inputs |
| Read-only API times out before execution | Usually, with a bound | Timeout classification and request correlation | The dependency remains unavailable |
| Write request has unknown outcome | No blind replay | Idempotency lookup or manual verification | External status cannot be confirmed |
| Permission or approval is denied | No | Record the decision and stop the branch | Policy or role mapping is disputed |
| Tool succeeds but next step loses the result | No | Session and turn trace, deterministic result marker | Handoff remains broken after replay |
| Dependent step starts without prerequisite data | No | Explicit checkpoint and dependency gate | Orchestrator state disagrees with business state |
| Compensation action fails | Only under a separate policy | Human takeover and audit record | The original side effect remains unresolved |
Do not use an infinite retry loop as a reliability design. It increases cost, hides the original fault, and can turn a temporary ambiguity into repeated external actions.
What to record in a reusable incident template
When a failure reaches you from production, capture the following in one record:
- User task and sanitized input.
- Agent run, session, turn, and item references.
- Tool name and schema version.
- Raw tool call and normalized executor input.
- Validation result.
- External request ID and operation status.
- Tool output returned to the Agent.
- Next Agent response.
- Side-effect status: none, completed, failed, pending, or unknown.
- Retry decision and reason.
- Rollback, compensation, or approval action.
- Final owner and next verification step.
This template lets another engineer reproduce the fault without access to the original workstation. It also makes it easier to compare a local run with a cloud AI Agent run, where worker restarts, network policy, credentials, and session persistence may differ.
Frequently asked questions
Why does the OpenAI Agents API sometimes skip my function tool?
Start by checking whether the model produced a tool call at all. Inspect the tool name, description, input schema, required fields, and the request messages sent to the model. If no call was emitted, the issue is tool selection or prompt context. If a call exists but your application ignores it, the failure is in dispatch rather than model selection.
How should I investigate failed tool parameters in the Agents API?
Compare the raw arguments with the executor contract before changing the prompt. Validate required fields, JSON types, enum values, nested objects, null handling, and any application-side type conversion. Log the validation error and the exact arguments, but redact credentials. A small set of fixed test inputs is more useful than repeatedly testing with changing user requests.
What should I do when an OpenAI Agent calls a tool but stops afterward?
Separate execution from result handoff. Confirm that the function ran, produced a result in the format expected by the Agent, and was attached to the correct turn or session. Then inspect the next model response. A successful business operation with a missing or malformed tool result can look like a reasoning failure, even though the real defect is in state propagation.
How can I add retries and rollback to multi-step Agent tools?
Classify failures before adding a retry loop. Retry transient transport or service errors with a bounded attempt policy, but do not automatically repeat payments, deletions, publishing actions, or other side effects. Use idempotency keys, approval checkpoints, compensation actions, and human takeover rules. Store the step status so recovery resumes from a known boundary instead of replaying the entire task.
If your current setup is a local workstation or an improvised cloud host, it may be fast to start but still leave you with inconsistent network access, unclear credential boundaries, process restarts, and no repeatable session environment. A rented Mac workspace is not automatically the right answer for a permanent, heavy workload or for tools that require physical hardware, but it can give you a cleaner temporary environment for reproducing Agent failures across controlled runs. Kvmkit's available remote Mac options are worth comparing when you need a separate test machine rather than another change to your production Agent.
If you still cannot reproduce the issue after tracing the five layers, move the workload into an isolated test environment, replay the same sanitized records, and keep the result handoff and side-effect checkpoints visible. You can review temporary Mac rental options before deciding whether temporary Mac access fits your debugging window.
FAQ
Why does the OpenAI Agents API sometimes skip my function tool?
Start by checking whether the model produced a tool call at all. Inspect the tool name, description, input schema, required fields, and the request messages sent to the model. If no call was emitted, the issue is tool selection or prompt context. If a call exists but your application ignores it, the failure is in dispatch rather than model selection.
How should I investigate failed tool parameters in the Agents API?
Compare the raw arguments with the executor contract before changing the prompt. Validate required fields, JSON types, enum values, nested objects, null handling, and any application-side type conversion. Log the validation error and the exact arguments, but redact credentials. A small set of fixed test inputs is more useful than repeatedly testing with changing user requests.
What should I do when an OpenAI Agent calls a tool but stops afterward?
Separate execution from result handoff. Confirm that the function ran, produced a result in the format expected by the Agent, and was attached to the correct turn or session. Then inspect the next model response. A successful business operation with a missing or malformed tool result can look like a reasoning failure, even though the real defect is in state propagation.
How can I add retries and rollback to multi-step Agent tools?
Classify failures before adding a retry loop. Retry transient transport or service errors with a bounded attempt policy, but do not automatically repeat payments, deletions, publishing actions, or other side effects. Use idempotency keys, approval checkpoints, compensation actions, and human takeover rules. Store the step status so recovery resumes from a known boundary instead of replaying the entire task.
Run CI/CD on M4 Mac mini — the hassle-free way
Xcode, Fastlane, CocoaPods, and SPM are first-class on macOS. Mac mini M4 unified memory keeps signing and archiving smooth; ~4W standby power suits 24/7 build nodes.