gildas-lormeau/SingleFile · error · Error
error.message + " (MCP)"
Error message
error.message + " (MCP)"
What it means
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.
Source
Thrown at src/core/bg/downloads.js:521
const client = new WebDAV(url, username, password);
business.setCancelCallback(taskId, () => client.abort());
return await client.upload(filename, content, { filenameConflictAction, prompt });
}
} catch (error) {
throw new Error(error.message + " (WebDAV)", { cause: error });
}
}
async function saveWithMCP(taskId, filename, content, serverUrl, authToken, { filenameConflictAction, prompt }) {
try {
const taskInfo = business.getTaskInfo(taskId);
if (!taskInfo || !taskInfo.cancelled) {
const client = new MCP(serverUrl, authToken);
business.setCancelCallback(taskId, () => client.abort());
return await client.upload(filename, content, { filenameConflictAction, prompt });
}
} catch (error) {
throw new Error(error.message + " (MCP)", { cause: error });
}
}
async function saveToGDrive(taskId, filename, blob, authOptions, uploadOptions) {
try {
await getAuthInfo(authOptions);
const taskInfo = business.getTaskInfo(taskId);
if (!taskInfo || !taskInfo.cancelled) {
return await gDrive.upload(filename, blob, uploadOptions, callback => business.setCancelCallback(taskId, callback));
}
}
catch (error) {
if (error.message == "invalid_token") {
let authInfo;
try {
authInfo = await gDrive.refreshAuthToken();
} catch (error) {
if (error.message == "unknown_token") {View on GitHub (pinned to 517fb7c5cf)
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
Example fix
// before
new MCP('http://localhost:9999', staleToken);
// after
new MCP('http://localhost:3000', await getFreshMcpToken()); Defensive patterns
Strategy: try-catch
Validate before calling
try {
const res = await fetch(serverUrl, { method: 'HEAD' });
if (!res.ok) throw new Error('MCP server not reachable: ' + res.status);
} catch (e) { throw new Error('MCP server unreachable before save: ' + e.message); } Type guard
function hasMCPConfig(o) {
try { return !!new URL(o.serverUrl) && typeof o.authToken === 'string' && o.authToken.length > 0; }
catch { return false; }
} Try / catch
try {
await saveWithMCP(taskId, filename, content, mcpOpts);
} catch (error) {
if (error.message.endsWith('(MCP)')) {
await refreshToken();
// optionally retry once
} else { throw error; }
} Prevention
- 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
When it happens
Trigger: Any rejection inside MCP.upload(filename, content, {filenameConflictAction, prompt}) from downloadContent/downloadCompressedContent: server unreachable, invalid/missing auth token, server error response, or abort.
Common situations: 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.
Related errors
- error.message + " (GitHub)"
- error.message + " (WebDAV)"
- error.message + " (RestFormApi)"
- error.message + " (S3)"
- error.message + " (Google Drive)"
AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01).
Data as JSON: /api/errors/ba632024659325c7.
Report an issue: GitHub.