{"record":{"id":"236ca2ca58652360","repo":"gildas-lormeau/SingleFile","slug":"error-message-webdav","errorCode":null,"errorMessage":"error.message + \" (WebDAV)\"","messagePattern":"error\\.message \\+ \" \\(WebDAV\\)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/bg/downloads.js","lineNumber":508,"sourceCode":"\t\t\tconst client = new S3(region, bucket, accessKey, secretKey, domain);\n\t\t\tbusiness.setCancelCallback(taskId, () => client.abort());\n\t\t\treturn await client.upload(filename, blob, { filenameConflictAction, prompt });\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(error.message + \" (S3)\", { cause: error });\n\t}\n}\n\nasync function saveWithWebDAV(taskId, filename, content, url, username, password, { filenameConflictAction, prompt }) {\n\ttry {\n\t\tconst taskInfo = business.getTaskInfo(taskId);\n\t\tif (!taskInfo || !taskInfo.cancelled) {\n\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 {","sourceCodeStart":490,"sourceCodeEnd":526,"githubUrl":"https://github.com/gildas-lormeau/SingleFile/blob/517fb7c5cf2096d89933b747e862d8ecf616a9f9/src/core/bg/downloads.js#L490-L526","documentation":"saveWithWebDAV wraps any error from the WebDAV client upload (new WebDAV(url, username, password).upload(...)) and rethrows with an \" (WebDAV)\" suffix, preserving the original error as cause. It identifies the WebDAV save destination as the failure point.","triggerScenarios":"Any rejection inside WebDAV.upload(filename, content, {filenameConflictAction, prompt}) from downloadContent/downloadCompressedContent: connection failure, 401 auth error, 404 path not found, or abort.","commonSituations":"Wrong WebDAV server URL (missing https:// or wrong path); incorrect username/password; server certificate invalid (self-signed); Nextcloud/ownCloud app password revoked; firewall blocking the server.","solutions":["Check error.cause for the HTTP status and verify the WebDAV URL is the full collection endpoint","Re-enter username/password (or app password for Nextcloud/ownCloud)","Confirm the server is reachable in a browser or via curl and its TLS certificate is valid","Ensure the target directory exists on the WebDAV server"],"exampleFix":"// before\nnew WebDAV('myserver.com/dav', user, pass); // missing scheme\n// after\nnew WebDAV('https://myserver.com/remote.php/dav/files/me', user, pass);","handlingStrategy":"validation","validationCode":"const u = new URL(url);\nif (!/^https?:$/.test(u.protocol)) throw new Error('WebDAV URL must be http(s)');\nif (!username || !password) throw new Error('Missing WebDAV credentials');","typeGuard":"function hasWebDAVConfig(o) {\n  try { const p = new URL(o.url).protocol; return (p === 'https:' || p === 'http:') &&\n    !!o.username && !!o.password; } catch { return false; }\n}","tryCatchPattern":"try {\n  await saveWithWebDAV(taskId, filename, content, webdavOpts);\n} catch (error) {\n  if (error.message.endsWith('(WebDAV)')) {\n    if (String(error.cause).includes('401')) { /* prompt for credentials */ }\n  } else { throw error; }\n}","preventionTips":["Use the full collection URL including https://","For Nextcloud/ownCloud use an app password, not the account password","Pre-probe the server with an OPTIONS/PROPFIND request at config time","Ensure the target directory exists before first save"],"tags":["webdav","upload","error-wrapping","network"],"backgroundTag":"webdav-upload-failed","analyzedSha":"517fb7c5cf2096d89933b747e862d8ecf616a9f9","analyzedAt":"2026-09-01T10:05:25.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}