Troubleshooting playbook
Start at the narrowest failing layer: server import → local MCP → nanoHUB session → gateway → OAuth/CORS → real host. Verify the deployed revision before reading the working tree.
Symptom |
Likely cause |
Fix / proof |
|---|---|---|
Server will not import |
Missing dependency, syntax error, or no module-level |
Run |
Tools work but |
|
Pin the full |
Local |
Tool is not registered with |
Confirm the published tool name, gateway registration, and |
|
A |
Call it through Streamable HTTP MCP after |
Async tools work locally but fail through the gateway |
|
Capture the initialize response header, send it on later calls, and verify gateway expose/forward rules |
|
Poll uses a different or missing session ID |
Reuse the exact session ID for |
SSE connects but no endpoint event arrives |
PHP/nginx buffering or a framework-generated empty body |
Use the raw SSE emit path, disable buffering, and inspect |
Browser shows an opaque CORS error |
CORS is present only on OPTIONS or required headers are not exposed |
Check actual 200/401/403 responses; emit ACAO everywhere and expose |
OAuth discovery never starts |
Gateway returned 403 or a 401 without a valid |
Missing/invalid authentication must return 401 with the challenge; reserve 403 for authenticated denials |
|
The |
Re-register once, use the returned ID exactly, and interpret the precise OAuth error table in |
Bogus-code exchange returns |
Client authentication succeeded; only the fake/expired code failed |
Treat this as the intended DCR smoke-test result |
Deployed fix changed nothing |
Gateway reused a session running an old tool revision |
Bump the app version, terminate stale sessions, reconnect, and verify |
|
Output does not match |
Validate the exact wire response; preserve raw JSON bytes through the gateway |
App tool succeeds but no UI appears |
Host did not declare the Apps capability, URI/mime metadata is wrong, or the resource is oversized |
Inspect initialize capabilities, |
Elicitation works locally but fails through REST |
Elicitation requires the bidirectional MCP session channel |
Invoke through a session-aware host and provide a conversational fallback |
Solver is killed or session becomes unresponsive |
Derived work, memory, disk, or result size was not bounded |
Estimate total work before launch; enforce time, concurrency, disk, and output ceilings |
CI is green with no useful coverage |
Tests skipped because an optional import failed |
Install test dependencies explicitly and fail CI on skipped offline tests or zero passes |
Layered command order
Run offline physics and contract tests.
Run
validate_server.pyin the deployment environment.Start locally and test initialize plus create→run→get.
Invoke the installed nanoHUB revision inside a session.
Run
smoke_live.shwithout DCR.Add a token, preserve the returned session header, and test Resources/Tasks.
Connect the real target host using
connecting-clients.md.
When a report contradicts local results, reproduce its exact host, tool revision, redirect URI, client ID, arguments, and session flow before drawing a conclusion.