AI_APICallError: tool_use blocks found without corresponding tool_result blocks #1784

Open
opened 2026-02-16 17:32:36 -05:00 by yindo · 13 comments
Owner

Originally created by @sahilchouksey on GitHub (Sep 21, 2025).

Originally assigned to: @rekram1-node on GitHub.

Description

Getting an AI_APICallError when tool_use blocks are not immediately followed by tool_result blocks.

Error Message

AI_APICallError: messages.69: `tool_use` ids were found without `tool_result` blocks immediately after: toolu_01X6jLG6TqrVeBTSEqq4ozEN. Each `tool_use` block must have a corresponding `tool_result` block in the next message.

Expected Behavior

The system should handle tool_use blocks properly and ensure each tool_use has a corresponding tool_result.

Additional Context

  • This appears to be a message formatting/validation issue
  • The error references a specific tool_use ID: toolu_01X6jLG6TqrVeBTSEqq4ozEN
  • Message index 69 suggests this occurs in longer conversations

Steps to Reproduce

This error occurred during normal usage when the AI made tool calls but the tool results weren't properly matched.

Originally created by @sahilchouksey on GitHub (Sep 21, 2025). Originally assigned to: @rekram1-node on GitHub. ## Description Getting an AI_APICallError when tool_use blocks are not immediately followed by tool_result blocks. ## Error Message ``` AI_APICallError: messages.69: `tool_use` ids were found without `tool_result` blocks immediately after: toolu_01X6jLG6TqrVeBTSEqq4ozEN. Each `tool_use` block must have a corresponding `tool_result` block in the next message. ``` ## Expected Behavior The system should handle tool_use blocks properly and ensure each tool_use has a corresponding tool_result. ## Additional Context - This appears to be a message formatting/validation issue - The error references a specific tool_use ID: toolu_01X6jLG6TqrVeBTSEqq4ozEN - Message index 69 suggests this occurs in longer conversations ## Steps to Reproduce This error occurred during normal usage when the AI made tool calls but the tool results weren't properly matched.
Author
Owner

@arsham commented on GitHub (Sep 21, 2025):

I have experienced this too. For now you could do this: type /undo, then enter. It will resend your last prompt and it usually works. Sometimes I had to restart opencode and load the session, then undo the last prompt and continue. It worked for me, hopefully it works for you tool

@arsham commented on GitHub (Sep 21, 2025): I have experienced this too. For now you could do this: type `/undo`, then enter. It will resend your last prompt and it usually works. Sometimes I had to restart opencode and load the session, then undo the last prompt and continue. It worked for me, hopefully it works for you tool
Author
Owner

@rekram1-node commented on GitHub (Sep 21, 2025):

can anyone share a session for this by chance?

@rekram1-node commented on GitHub (Sep 21, 2025): can anyone share a session for this by chance?
Author
Owner

@sahilchouksey commented on GitHub (Sep 22, 2025):

I am not able to find the session for this one. If this error appears again, I will provide the session in this thread.

@sahilchouksey commented on GitHub (Sep 22, 2025): I am not able to find the session for this one. If this error appears again, I will provide the session in this thread.
Author
Owner

@Davincible commented on GitHub (Dec 9, 2025):

@rekram1-node this just happened to me on Opus 4.5, opencode version 1.0.134

Session log

Optimizing YouTube transcript retrieval

Session ID: ses_4fc89a65dffeXDBJYG337eRw9o
Created: 12/9/2025, 3:14:06 PM
Updated: 12/9/2025, 3:25:33 PM


User

At the end, I always use this library to get transcripts. Right now, we take the difficult route, being downloading the audio file, and then transcribing it. However for a lot of videos there is a transcript available directly from youtube, and then we can bypass the manual download entirely.

I found this library online: https://github.com/jdepoix/youtube-transcript-api

What I want the new flow to be when syncing a video:

  1. CHeck if there is a transcript available directly
  2. If not, take the original route. If there is, download transcript, and proceed

We can do these steps in prallel as well. E.g. we synchronously go through the video list, but when we need to actually download an mp3, we can do that in a different worker, and already check the next video for a direct transcript, then queue up MP3 downloads with the worker

This is a brief overview of what I want. Please think this through in depth, create a complete plan and spect to implement this, and write it down in a file


Assistant

I'll analyze this request thoroughly. Let me first understand the current implementation and then explore the youtube-transcript-api library to create a comprehensive plan.

Tool: task
Tool: webfetch

Assistant

I now have a good understanding of both the current codebase and the youtube-transcript-api library. Let me ask some clarifying questions before I create a detailed plan.

Clarifying Questions

Before I create the complete spec, I have a few questions to ensure the plan matches your expectations:

  1. Transcript source preference: When a YouTube transcript is available, should we:

    • Always prefer YouTube's transcript over MLX Whisper transcription?
    • Allow user configuration (e.g., --prefer-youtube-transcript flag)?
    • What if YouTube has auto-generated captions vs. manual captions - do you have a preference?
  2. Language handling: The youtube-transcript-api supports multiple languages. Should we:

    • Try to match the user's configured language preference?
    • Fall back to English if the preferred language isn't available?
    • Store language metadata in the database?
  3. Transcript format consistency: YouTube transcripts have timestamps for each snippet. Should we:

    • Keep the same output format as MLX Whisper (just text with metadata header)?
    • Preserve timestamps in a different format?
    • Store a flag indicating the transcript source (youtube vs whisper)?
  4. Parallel worker architecture: You mentioned:

    "we synchronously go through the video list, but when we need to actually download an mp3, we can do that in a different worker"

    Currently downloads are sequential (main thread) and transcriptions are concurrent (worker thread). Are you proposing:

    • Option A: Keep downloads sequential, but check YouTube transcripts first (fast), then queue MP3 downloads only when needed
    • Option B: Add a separate download worker pool for parallel MP3 downloads
    • Option C: Something else?
  5. Error handling: If YouTube transcript fetch fails (e.g., video has no transcript, IP blocked), should we:

    • Silently fall back to download+transcribe?
    • Log a warning and fall back?
    • Retry with different language codes?
  6. Database schema: Do you want to track:

    • Which videos have YouTube transcripts available?
    • Which source was used for each transcript (youtube_api vs whisper)?
    • Transcript language?

Let me know your thoughts on these questions and I'll create a comprehensive implementation plan.


User

  1. Yes, always prefer from the API, both auto generated or manual
  2. always english, I don't care about other languages
  3. Don't care about timestamps. Just text like we get with whisper
  4. You can architect it, but I think: 1 worker to check transcript API (fast), if not, queue and send off to 1 download worker, then we have the transcript worker after that
  5. If IP blocked, please log it out to console as a nice warning, and fallback to download. No transcript available is expected behavior and then we fall back to mp3
  6. If currently we track anything about videos in e.g. database somewhere, then sure you can add that. Otherwise don't bother

Assistant

Thank you for the clarifications. Now I have everything I need to create a comprehensive plan. Let me write this to a spec file.

Tool: read
Tool: read
Tool: read

Assistant

Now I have a complete understanding of the codebase. Let me also check the config and transcriber for any relevant details:

Tool: read
Tool: read

Assistant

Now I have all the information I need. Let me create a comprehensive spec document:

Tool: write

Now I have all the context I need. Let me write a comprehensive specification document:

Tool: write

Assistant


I don't want to undo the last whole message as I think that would delete the result, but having to start a whole new conversation is also annoying

Image
@Davincible commented on GitHub (Dec 9, 2025): @rekram1-node this just happened to me on Opus 4.5, opencode version 1.0.134 <details> <summary>Session log</summary> # Optimizing YouTube transcript retrieval **Session ID:** ses_4fc89a65dffeXDBJYG337eRw9o **Created:** 12/9/2025, 3:14:06 PM **Updated:** 12/9/2025, 3:25:33 PM --- ## User At the end, I always use this library to get transcripts. Right now, we take the difficult route, being downloading the audio file, and then transcribing it. However for a lot of videos there is a transcript available directly from youtube, and then we can bypass the manual download entirely. I found this library online: https://github.com/jdepoix/youtube-transcript-api What I want the new flow to be when syncing a video: 1. CHeck if there is a transcript available directly 2. If not, take the original route. If there is, download transcript, and proceed We can do these steps in prallel as well. E.g. we synchronously go through the video list, but when we need to actually download an mp3, we can do that in a different worker, and already check the next video for a direct transcript, then queue up MP3 downloads with the worker This is a brief overview of what I want. Please think this through in depth, create a complete plan and spect to implement this, and write it down in a file --- ## Assistant I'll analyze this request thoroughly. Let me first understand the current implementation and then explore the youtube-transcript-api library to create a comprehensive plan. ``` Tool: task ``` ``` Tool: webfetch ``` --- ## Assistant I now have a good understanding of both the current codebase and the youtube-transcript-api library. Let me ask some clarifying questions before I create a detailed plan. ## Clarifying Questions Before I create the complete spec, I have a few questions to ensure the plan matches your expectations: 1. **Transcript source preference**: When a YouTube transcript is available, should we: - Always prefer YouTube's transcript over MLX Whisper transcription? - Allow user configuration (e.g., `--prefer-youtube-transcript` flag)? - What if YouTube has auto-generated captions vs. manual captions - do you have a preference? 2. **Language handling**: The youtube-transcript-api supports multiple languages. Should we: - Try to match the user's configured language preference? - Fall back to English if the preferred language isn't available? - Store language metadata in the database? 3. **Transcript format consistency**: YouTube transcripts have timestamps for each snippet. Should we: - Keep the same output format as MLX Whisper (just text with metadata header)? - Preserve timestamps in a different format? - Store a flag indicating the transcript source (youtube vs whisper)? 4. **Parallel worker architecture**: You mentioned: > "we synchronously go through the video list, but when we need to actually download an mp3, we can do that in a different worker" Currently downloads are sequential (main thread) and transcriptions are concurrent (worker thread). Are you proposing: - **Option A**: Keep downloads sequential, but check YouTube transcripts first (fast), then queue MP3 downloads only when needed - **Option B**: Add a separate download worker pool for parallel MP3 downloads - **Option C**: Something else? 5. **Error handling**: If YouTube transcript fetch fails (e.g., video has no transcript, IP blocked), should we: - Silently fall back to download+transcribe? - Log a warning and fall back? - Retry with different language codes? 6. **Database schema**: Do you want to track: - Which videos have YouTube transcripts available? - Which source was used for each transcript (youtube_api vs whisper)? - Transcript language? Let me know your thoughts on these questions and I'll create a comprehensive implementation plan. --- ## User 1. Yes, always prefer from the API, both auto generated or manual 2. always english, I don't care about other languages 3. Don't care about timestamps. Just text like we get with whisper 4. You can architect it, but I think: 1 worker to check transcript API (fast), if not, queue and send off to 1 download worker, then we have the transcript worker after that 5. If IP blocked, please log it out to console as a nice warning, and fallback to download. No transcript available is expected behavior and then we fall back to mp3 6. If currently we track anything about videos in e.g. database somewhere, then sure you can add that. Otherwise don't bother --- ## Assistant Thank you for the clarifications. Now I have everything I need to create a comprehensive plan. Let me write this to a spec file. ``` Tool: read ``` ``` Tool: read ``` ``` Tool: read ``` --- ## Assistant Now I have a complete understanding of the codebase. Let me also check the config and transcriber for any relevant details: ``` Tool: read ``` ``` Tool: read ``` --- ## Assistant Now I have all the information I need. Let me create a comprehensive spec document: ``` Tool: write ``` Now I have all the context I need. Let me write a comprehensive specification document: ``` Tool: write ``` --- ## Assistant --- </details> I don't want to undo the last whole message as I think that would delete the result, but having to start a whole new conversation is also annoying <img width="833" height="413" alt="Image" src="https://github.com/user-attachments/assets/b9494884-567a-4324-be01-c5b520a90286" />
Author
Owner

@Mishkun commented on GitHub (Dec 16, 2025):

@rekram1-node Hey, what's the priority on this? It is a single most annoying bug that can kill the long running session randomly without a chance to recover or summarize to handover to another session. And it happens to me regularily enough to be a pain

@Mishkun commented on GitHub (Dec 16, 2025): @rekram1-node Hey, what's the priority on this? It is a single most annoying bug that can kill the long running session randomly without a chance to recover or summarize to handover to another session. And it happens to me regularily enough to be a pain
Author
Owner

@rekram1-node commented on GitHub (Dec 16, 2025):

@Mishkun if you can gimme a opencode export > session.json I can fix it

But I need the actual session data to figure out where it went wrong

@rekram1-node commented on GitHub (Dec 16, 2025): @Mishkun if you can gimme a `opencode export > session.json` I can fix it But I need the actual session data to figure out where it went wrong
Author
Owner

@rrohrer commented on GitHub (Dec 16, 2025):

session-ses_4d6d.md
session.json

@rekram1-node not OP but here is a session md and json from me hitting this in version *.164

@rrohrer commented on GitHub (Dec 16, 2025): [session-ses_4d6d.md](https://github.com/user-attachments/files/24200942/session-ses_4d6d.md) [session.json](https://github.com/user-attachments/files/24200943/session.json) @rekram1-node not OP but here is a session md and json from me hitting this in version *.164
Author
Owner

@rekram1-node commented on GitHub (Dec 16, 2025):

okay on my list to checkout here

@rekram1-node commented on GitHub (Dec 16, 2025): okay on my list to checkout here
Author
Owner

@Mishkun commented on GitHub (Dec 23, 2025):

#1662 related

@Mishkun commented on GitHub (Dec 23, 2025): #1662 related
Author
Owner

@rekram1-node commented on GitHub (Jan 2, 2026):

I think there was a fix in upstream ai-sdk package that we updated to, not sure if it resolved this or not

@rekram1-node commented on GitHub (Jan 2, 2026): I think there was a fix in upstream ai-sdk package that we updated to, not sure if it resolved this or not
Author
Owner

@arielpollack commented on GitHub (Jan 14, 2026):

still happens, and in most of my sessions it evetualy happens

@arielpollack commented on GitHub (Jan 14, 2026): still happens, and in most of my sessions it evetualy happens
Author
Owner

@zyriab commented on GitHub (Jan 24, 2026):

it happens all the time, it makes working with Anthropic models pretty hard :(

@zyriab commented on GitHub (Jan 24, 2026): it happens all the time, it makes working with Anthropic models pretty hard :(
Author
Owner

@Yukimir commented on GitHub (Jan 24, 2026):

i find that if the agent called a command that print nothing (such as mkdir), the framework will not add the tool call result to the message list and cause this problem.

@Yukimir commented on GitHub (Jan 24, 2026): i find that if the agent called a command that print nothing (such as mkdir), the framework will not add the tool call result to the message list and cause this problem.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#1784