Skip to content

fix(opencode): prevent Copilot 400 when tool description is empty#14647

Open
amsminn wants to merge 1 commit intoanomalyco:devfrom
amsminn:fix/14488-mcp-tool-description-fallback
Open

fix(opencode): prevent Copilot 400 when tool description is empty#14647
amsminn wants to merge 1 commit intoanomalyco:devfrom
amsminn:fix/14488-mcp-tool-description-fallback

Conversation

@amsminn
Copy link
Copy Markdown

@amsminn amsminn commented Feb 22, 2026

Issue for this PR

Closes #14488

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Fixes Copilot request validation failure when an MCP/OpenAI-compatible tool has an empty description.

Sending tools[].function.description: "" to Copilot Chat Completions returns HTTP 400 Bad Request (reproduced on 2026-02-22), while omitting function.description returns HTTP 200. Because the field is optional in Copilot SDK types, this PR normalizes empty/whitespace descriptions to undefined (field omission) instead of injecting synthetic text like No description. This keeps the original tool meaning and removes the 400 failure:

This PR omits empty/whitespace function.description values and adds two tests.

Changed code:

  • packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts:53
  • packages/opencode/test/provider/copilot/copilot-chat-model.test.ts:591
  • packages/opencode/test/provider/copilot/copilot-chat-model.test.ts:596

How did you verify your code works?

Verification date: 2026-02-22

  1. Reproduced issue with Copilot API (claude-sonnet-4.6, stream=true):
    • request with function.description="" -> HTTP 400 (Bad Request)
  2. Verified fix behavior:
    • same request with function.description omitted -> HTTP 200 (SSE stream starts)
  3. Ran local tests:
    • bun test test/provider/copilot/copilot-chat-model.test.ts (run from packages/opencode)
    • Result: 13 pass, 0 fail
  4. Reproduction + validation commands used:
cd <repo-root>
tok=$(gh auth token)

code=$(curl -sS -o /tmp/copilot_empty.txt -w "%{http_code}" https://api.githubcopilot.com/chat/completions \
  -H "Authorization: Bearer $tok" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-4.6","messages":[{"role":"user","content":"hi"}],"tools":[{"type":"function","function":{"name":"t","description":"","parameters":{"type":"object","properties":{"x":{"type":"string"}}}}}],"tool_choice":"auto","stream":true}')
echo "empty_description_status=$code"
head -n 3 /tmp/copilot_empty.txt

code=$(curl -sS -o /tmp/copilot_omit.txt -w "%{http_code}" https://api.githubcopilot.com/chat/completions \
  -H "Authorization: Bearer $tok" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-4.6","messages":[{"role":"user","content":"hi"}],"tools":[{"type":"function","function":{"name":"t","parameters":{"type":"object","properties":{"x":{"type":"string"}}}}}],"tool_choice":"auto","stream":true}')
echo "omit_description_status=$code"
head -n 3 /tmp/copilot_omit.txt

cd packages/opencode
bun test test/provider/copilot/copilot-chat-model.test.ts

Screenshots / recordings

N/A - no UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@amsminn amsminn force-pushed the fix/14488-mcp-tool-description-fallback branch 9 times, most recently from c3cafe6 to 4582f5a Compare February 25, 2026 01:04
@amsminn amsminn force-pushed the fix/14488-mcp-tool-description-fallback branch 4 times, most recently from c5725f1 to 6e34c95 Compare February 28, 2026 02:51
@amsminn amsminn force-pushed the fix/14488-mcp-tool-description-fallback branch 2 times, most recently from d885156 to b5a48a8 Compare March 2, 2026 01:16
@amsminn amsminn force-pushed the fix/14488-mcp-tool-description-fallback branch from bfb9011 to f90ffb2 Compare March 5, 2026 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AI_APICallError (400 Bad Request) with GitHub Copilot when MCP tool has empty description, affects claude-sonnet-4.6 / claude-opus-4.6 only

1 participant