Skip to content

fix: panic recovery returns proper error result; safe tokenizer nil handling [#318]#320

Merged
Dumbris merged 2 commits intomainfrom
fix/panic-recovery-nil-tokenizer-318
Mar 8, 2026
Merged

fix: panic recovery returns proper error result; safe tokenizer nil handling [#318]#320
Dumbris merged 2 commits intomainfrom
fix/panic-recovery-nil-tokenizer-318

Conversation

@Dumbris
Copy link
Contributor

@Dumbris Dumbris commented Mar 8, 2026

Summary

Fixes #318handleCallToolVariant panic recovery returned (nil, nil), causing a second unrecovered panic in mcp-go and dropping the HTTP connection.

  • Named return values in panic recovery: recover() now sets callResult via named returns, returning a proper error tool result instead of (nil, nil). Applied to both handleCallToolVariant and legacy handleCallTool.
  • Safe tokenizer access: Replaced unsafe tokenizer.(*DefaultTokenizer).GetDefaultEncoding() with SafeGetDefaultEncoding() — handles nil interface, nil underlying value, and non-DefaultTokenizer types.
  • Skip tiktoken validation when disabled: NewTokenizer(encoding, logger, false) no longer calls tiktoken.GetEncoding(), so the fallback always succeeds even with a corrupted cache.
  • Guard nil serverConfig: GenerateServerID(serverConfig) is now guarded against nil (when storage lookup fails).

Test plan

  • TestNewTokenizerDisabledWithInvalidEncoding — disabled tokenizer created with corrupted encoding
  • TestNilTokenizerInterfaceSafety — nil concrete in interface doesn't panic
  • TestSafeGetDefaultEncoding — all nil/valid/interface scenarios
  • TestHandleCallToolVariant_PanicRecovery — never returns (nil, nil)
  • Race detection passes on all new tests
  • E2E tests pass (./scripts/test-api-e2e.sh)

🤖 Generated with Claude Code

…andling [#318]

Three independent fixes for the crash chain reported in #318:

1. Named return values in panic recovery (handleCallToolVariant, handleCallTool):
   recover() now sets callResult via named returns instead of returning (nil, nil),
   preventing the second unrecovered panic in mcp-go's HandleMessage.

2. Safe tokenizer access (SafeGetDefaultEncoding):
   Replaces unsafe type assertion `tokenizer.(*DefaultTokenizer).GetDefaultEncoding()`
   with a nil-safe helper that handles nil interface, nil underlying value, and
   non-DefaultTokenizer implementations.

3. Skip tiktoken validation for disabled tokenizer (NewTokenizer):
   When enabled=false, encoding validation is skipped so the fallback path always
   succeeds even with a corrupted tiktoken cache.

4. Guard against nil serverConfig in GenerateServerID calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 8, 2026

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7e9c698
Status: ✅  Deploy successful!
Preview URL: https://fee3adb4.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-panic-recovery-nil-token.mcpproxy-docs.pages.dev

View logs

@github-actions
Copy link

github-actions bot commented Mar 8, 2026

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/panic-recovery-nil-tokenizer-318

Available Artifacts

  • archive-darwin-amd64 (24 MB)
  • archive-darwin-arm64 (21 MB)
  • archive-linux-amd64 (13 MB)
  • archive-linux-arm64 (11 MB)
  • archive-windows-amd64 (23 MB)
  • archive-windows-arm64 (21 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (26 MB)
  • installer-dmg-darwin-arm64 (24 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 22814426068 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

…#318]

Rewrite panic recovery tests to trigger real panics by nil-ing out
proxy.storage, causing nil pointer dereference inside the handler.
This verifies the named-return-value recover block actually catches
panics and returns a proper error result (not nil, nil).

Three subtests:
- normal error path (server not found) returns error result
- panic in handleCallToolVariant returns error result via recover
- panic in legacy handleCallTool returns error result via recover

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Dumbris Dumbris merged commit 83508f5 into main Mar 8, 2026
23 checks passed
@Dumbris Dumbris deleted the fix/panic-recovery-nil-tokenizer-318 branch March 8, 2026 05:22
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.

handleCallToolVariant: panic recovery returns (nil, nil) crashing mcp-go; triggered by tiktoken cache corruption

2 participants