{"record":{"id":"b4d4028406666776","repo":"unslothai/unsloth","slug":"mcp-server-not-found","errorCode":null,"errorMessage":"MCP server not found","messagePattern":"MCP server not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"studio/backend/routes/mcp_servers.py","lineNumber":213,"sourceCode":"        if payload.use_oauth is None:\n            raise HTTPException(status_code = 400, detail = \"use_oauth must be true or false\")\n        changes[\"use_oauth\"] = payload.use_oauth\n    # stdio is OAuth-less: drop a stale OAuth flag when switching to a command.\n    if \"url\" in changes and is_stdio(changes[\"url\"]):\n        changes[\"use_oauth\"] = False\n    return changes\n\n\n@router.put(\"/{server_id}\", response_model = McpServerResponse)\nasync def update_mcp_server(\n    server_id: str,\n    payload: McpServerUpdate,\n    current_subject: str = Depends(get_current_subject),\n    via_api_key: ViaApiKey = False,\n):\n    old = mcp_servers_db.get_server(server_id)\n    if not old:\n        raise HTTPException(status_code = 404, detail = \"MCP server not found\")\n    changes = _changes_from_payload(payload)\n    if not changes:\n        raise HTTPException(status_code = 400, detail = \"No fields to update\")\n    # Both directions, so an API key can neither repoint an http row at a command\n    # nor edit a stdio row's env/name/enabled flag. Before every side effect, so a\n    # refusal leaves the row, its OAuth tokens, cache and sessions untouched.\n    if is_stdio(old[\"url\"]) or is_stdio(changes.get(\"url\", old[\"url\"])):\n        require_ui_session_for_local_commands(via_api_key)\n    # headers == HTTP headers (remote) or env vars (stdio). On a transport-type\n    # switch with no new headers, drop the old ones so env secrets aren't\n    # re-sent as HTTP headers (or vice versa).\n    if (\n        \"url\" in changes\n        and is_stdio(changes[\"url\"]) != is_stdio(old[\"url\"])\n        and \"headers_json\" not in changes\n    ):\n        changes[\"headers_json\"] = None\n    # Clear persisted OAuth tokens when the URL changes or OAuth is disabled;","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/mcp_servers.py#L195-L231","documentation":"404 from the PUT update endpoint when mcp_servers_db.get_server(server_id) returns no row. The id is the 16-hex-char identifier assigned at create time (uuid4().hex[:16]); an unknown, mistyped, or deleted id yields this 404 before any payload validation side effects.","triggerScenarios":"PUT /api/mcp-servers/{server_id} with an id that was deleted, truncated/typo'd, or invented; also stale UI sessions holding ids from a reset database.","commonSituations":"Editing an MCP server in one tab after deleting it in another; a recreated database losing rows while the client caches old ids; scripts re-using hard-coded ids after a re-install.","solutions":["List servers (GET /api/mcp-servers/) and use the current id from the response.","Handle 404 by refreshing the local list and re-selecting the row instead of retrying blindly.","If the row must exist, re-create it with POST and store the returned id."],"exampleFix":"// before\nawait api.put(`/api/mcp-servers/${cachedId}`, payload); // 404 after row deleted elsewhere\n\n// after\nconst servers = await api.get('/api/mcp-servers/').then(r => r.json());\nconst row = servers.find(s => s.display_name === name);\nif (!row) throw new Error('Server row gone — recreate it');\nawait api.put(`/api/mcp-servers/${row.id}`, payload);","handlingStrategy":"validation","validationCode":"const servers = await api.get('/api/mcp-servers/').then(r => r.json());\nif (!servers.some(s => s.id === serverId)) throw new Error('Unknown MCP server id');","typeGuard":"async function serverExists(id) { const r = await api.get(`/api/mcp-servers/${id}`); return r.status === 200; }","tryCatchPattern":"catch (e) { if (e.status === 404) { await refreshServerList(); return null; } throw e; }","preventionTips":["Refresh the id list before editing rows touched by other tabs/sessions.","Store ids from the create response, never hard-code them."],"tags":["mcp","http-404","crud","stale-id"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}