gildas-lormeau/SingleFile · error · Error
writeResponse.error || "Failed to write file via MCP"
Error message
writeResponse.error || "Failed to write file via MCP"
What it means
The MCP library's upload calls writeFile on the configured MCP server; if the response indicates success === false, it throws writeResponse.error if present, otherwise the generic "Failed to write file via MCP". This means the server accepted the request but could not write the file — the reason is server-defined and only available via writeResponse.error.
Source
Thrown at src/lib/mcp/mcp.js:108
path = await prompt(path);
if (path) {
return await upload(path, content, options);
} else {
return { url: path, skipped: true };
}
} else {
options.filenameConflictAction = CONFLICT_ACTION_UNIQUIFY;
return await upload(path, content, options);
}
}
}
const writeResponse = await writeFile(serverUrl, authToken, path, content, signal, getRequestId);
if (writeResponse.success) {
return { url: path };
} else {
throw new Error(writeResponse.error || "Failed to write file via MCP");
}
} catch (error) {
if (error.name != ABORT_ERROR_NAME) {
throw error;
}
}
}
async function checkFileExists(serverUrl, authToken, path, signal, getRequestId) {
const requestBody = {
jsonrpc: MCP_JSONRPC_VERSION,
id: getRequestId(),
method: "tools/call",
params: {
name: "get_file_info",
arguments: {
path: path
}View on GitHub (pinned to 517fb7c5cf)
Solutions
- Inspect the full writeResponse (log it before throwing) to capture any server-provided error detail.
- Verify the target path is inside the MCP server's configured allowed directories.
- Confirm the server's write tool is reachable and its result shape matches {success: boolean, error?: string}.
- Test the same write with an MCP inspector/client against serverUrl to isolate client vs server.
Example fix
// before
await mcp.upload(url, token, path, content); // Error: Failed to write file via MCP
// after
const res = await writeFile(serverUrl, token, path, content, signal, getRequestId);
if (!res.success) throw new Error(`MCP write failed for ${path}: ${res.error ?? JSON.stringify(res)}`); Defensive patterns
Strategy: type-guard
Validate before calling
function isWritableMcpPath(serverConfig, path) {
return serverConfig.allowedRoots.some(root => path.startsWith(root));
}
if (!isWritableMcpPath(cfg, path)) throw new Error("path outside MCP server allowed roots"); Type guard
function isWriteSuccess(r) {
return r !== null && typeof r === "object" && r.success === true;
}
// usage: const res = await writeFile(...); if (!isWriteSuccess(res)) handle(res.error); Try / catch
try { await mcp.upload(url, token, path, content); }
catch (e) {
// e.message is writeResponse.error or the generic fallback
logMcpWriteFailure(path, e.message);
throw e;
} Prevention
- Keep target paths inside the MCP server's allowed directories
- Confirm the server's write tool result includes an `error` field for diagnostics
- Validate serverUrl and tool contract with an MCP inspector during setup
When it happens
Trigger: writeFile resolves with {success: false} and no error field — e.g. the MCP tool returned an error result, the path is not writable on the server, the server-side tool rejected the content, or the server returned an empty/unexpected success payload.
Common situations: MCP server filesystem tool lacks permission for the target directory; path outside the server's allowed roots; server tool returning isError results without a message; misconfigured serverUrl pointing at a server whose write tool has a different contract.
Related errors
- MCP server error: ${response.status} ${response.statusText}
- error.message + " (MCP)"
- data.error.message
AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01).
Data as JSON: /api/errors/180c1d098cbb692b.
Report an issue: GitHub.