{"record":{"id":"ba632024659325c7","repo":"gildas-lormeau/SingleFile","slug":"error-message-mcp","errorCode":null,"errorMessage":"error.message + \" (MCP)\"","messagePattern":"error\\.message \\+ \" \\(MCP\\)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/bg/downloads.js","lineNumber":521,"sourceCode":"\t\t\tconst client = new WebDAV(url, username, password);\n\t\t\tbusiness.setCancelCallback(taskId, () => client.abort());\n\t\t\treturn await client.upload(filename, content, { filenameConflictAction, prompt });\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(error.message + \" (WebDAV)\", { cause: error });\n\t}\n}\n\nasync function saveWithMCP(taskId, filename, content, serverUrl, authToken, { filenameConflictAction, prompt }) {\n\ttry {\n\t\tconst taskInfo = business.getTaskInfo(taskId);\n\t\tif (!taskInfo || !taskInfo.cancelled) {\n\t\t\tconst client = new MCP(serverUrl, authToken);\n\t\t\tbusiness.setCancelCallback(taskId, () => client.abort());\n\t\t\treturn await client.upload(filename, content, { filenameConflictAction, prompt });\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(error.message + \" (MCP)\", { cause: error });\n\t}\n}\n\nasync function saveToGDrive(taskId, filename, blob, authOptions, uploadOptions) {\n\ttry {\n\t\tawait getAuthInfo(authOptions);\n\t\tconst taskInfo = business.getTaskInfo(taskId);\n\t\tif (!taskInfo || !taskInfo.cancelled) {\n\t\t\treturn await gDrive.upload(filename, blob, uploadOptions, callback => business.setCancelCallback(taskId, callback));\n\t\t}\n\t}\n\tcatch (error) {\n\t\tif (error.message == \"invalid_token\") {\n\t\t\tlet authInfo;\n\t\t\ttry {\n\t\t\t\tauthInfo = await gDrive.refreshAuthToken();\n\t\t\t} catch (error) {\n\t\t\t\tif (error.message == \"unknown_token\") {","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/gildas-lormeau/SingleFile/blob/517fb7c5cf2096d89933b747e862d8ecf616a9f9/src/core/bg/downloads.js#L503-L539","documentation":"saveWithMCP wraps any error from the MCP client upload (new MCP(serverUrl, authToken).upload(...)) and rethrows with an \" (MCP)\" suffix plus the original error as cause. The suffix identifies the MCP server destination as the failure point.","triggerScenarios":"Any rejection inside MCP.upload(filename, content, {filenameConflictAction, prompt}) from downloadContent/downloadCompressedContent: server unreachable, invalid/missing auth token, server error response, or abort.","commonSituations":"MCP server URL mistyped or server down; auth token expired or rotated; server rejecting the upload endpoint/CORS; reverse proxy returning 502/504 during large uploads.","solutions":["Inspect error.cause and verify serverUrl points at a running MCP server","Regenerate/refresh the authToken and retry","Test the server endpoint with curl to see the raw status code","Check proxy/timeout settings if uploads of large pages fail midway"],"exampleFix":"// before\nnew MCP('http://localhost:9999', staleToken);\n// after\nnew MCP('http://localhost:3000', await getFreshMcpToken());","handlingStrategy":"try-catch","validationCode":"try {\n  const res = await fetch(serverUrl, { method: 'HEAD' });\n  if (!res.ok) throw new Error('MCP server not reachable: ' + res.status);\n} catch (e) { throw new Error('MCP server unreachable before save: ' + e.message); }","typeGuard":"function hasMCPConfig(o) {\n  try { return !!new URL(o.serverUrl) && typeof o.authToken === 'string' && o.authToken.length > 0; }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  await saveWithMCP(taskId, filename, content, mcpOpts);\n} catch (error) {\n  if (error.message.endsWith('(MCP)')) {\n    await refreshToken();\n    // optionally retry once\n  } else { throw error; }\n}","preventionTips":["Health-check the MCP server before long batch saves","Rotate auth tokens on a schedule","Increase proxy timeouts for large pages","Log error.cause to distinguish auth vs network failures"],"tags":["mcp","upload","error-wrapping","network"],"backgroundTag":"mcp-upload-failed","analyzedSha":"517fb7c5cf2096d89933b747e862d8ecf616a9f9","analyzedAt":"2026-09-01T10:05:25.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}