laurent22/joplin · error · Error

Invalid WebDAV resource format: ${JSON.stringify(resource)}

Error message

Invalid WebDAV resource format: ${JSON.stringify(resource)}

What it means

Thrown by the WebDAV driver when parsing a PROPFIND response: statFromResource_() expects each d:response element to contain a d:propstat array. If the parsed resource lacks a recognizable propstat, the server returned a non-standard or malformed multi-status body, and the driver cannot extract type/timestamp info, so it aborts.

Source

Thrown at packages/lib/file-api-driver-webdav.js:44

	}

	async stat(path) {
		try {
			const result = await this.api().execPropFind(path, 0, ['d:getlastmodified', 'd:resourcetype']);

			const resource = this.api().objectFromJson(result, ['d:multistatus', 'd:response', 0]);
			return this.statFromResource_(resource, path);
		} catch (error) {
			if (error.code === 404) return null;
			throw error;
		}
	}

	statFromResource_(resource, path) {
		// WebDAV implementations are always slightly different from one server to another but, at the minimum,
		// a resource should have a propstat key - if not it's probably an error.
		const propStat = this.api().arrayFromJson(resource, ['d:propstat']);
		if (!Array.isArray(propStat)) throw new Error(`Invalid WebDAV resource format: ${JSON.stringify(resource)}`);

		// Disabled for now to try to fix this: https://github.com/laurent22/joplin/issues/624
		//
		// const httpStatusLine = this.api().stringFromJson(resource, ['d:propstat',0,'d:status', 0]);
		// if ( typeof httpStatusLine === 'string' && httpStatusLine.indexOf('404') >= 0 ) throw  new JoplinError(resource, 404);

		const resourceTypes = this.api().resourcePropByName(resource, 'array', 'd:resourcetype');
		let isDir = false;
		if (Array.isArray(resourceTypes)) {
			for (let i = 0; i < resourceTypes.length; i++) {
				const t = resourceTypes[i];
				if (typeof t === 'object' && 'd:collection' in t) {
					isDir = true;
					break;
				}
			}
		}

View on GitHub (pinned to 2654b33620)

Solutions

  1. Verify the WebDAV URL is correct and points at a real WebDAV endpoint (test with curl PROPFIND).
  2. Check credentials — an HTML auth page is often mis-parsed as a resource; re-link with valid user/pass.
  3. Confirm namespace handling — some servers use 'D:' not 'd:'; ensure the client lower-cases or maps prefixes.
  4. Capture the raw PROPFIND response to see what the server actually sent and adapt the parser.

Example fix

// before
const propStat = this.api().arrayFromJson(resource, ['d:propstat']);
if (!Array.isArray(propStat)) throw new Error(`Invalid WebDAV resource format: ${JSON.stringify(resource)}`);
// after - fall back to alternate namespace and surface a clearer cause
let propStat = this.api().arrayFromJson(resource, ['d:propstat']) || this.api().arrayFromJson(resource, ['D:propstat']);
if (!Array.isArray(propStat)) throw new Error(`WebDAV resource missing propstat (check URL/auth): ${JSON.stringify(resource).slice(0, 200)}`);
Defensive patterns

Strategy: validation

Validate before calling

// Probe the endpoint with a PROPFIND before syncing.
const r = await fetch(baseUrl, { method: 'PROPFIND', headers: { Depth: '0' } });
if (!r.ok || !(await r.text()).includes('propstat')) {
  throw new Error('Configured URL is not a standards-compliant WebDAV endpoint.');
}

Type guard

function hasValidPropStat(resource: any): boolean {
  return !!resource && Array.isArray(resource?.['d:propstat'] ?? resource?.['D:propstat']);
}

Try / catch

try {
  return await driver.stat(path);
} catch (e) {
  if (/Invalid WebDAV resource format/.test(e.message)) {
    throw new Error('WebDAV server returned a malformed PROPFIND; check URL and credentials.');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling stat() on a WebDAV server whose PROPFIND reply omits propstat — e.g. server returns an error inside the response element, uses a different XML namespace prefix, or returns plain text/HTML instead of multistatus XML.

Common situations: Misconfigured WebDAV server (Nextcloud, Seafile, nginx, Apache) returning non-standard XML; wrong base URL pointing at a non-WebDAV endpoint; namespace prefix mismatch (d: vs D:); authentication failure returning an HTML login page parsed as a resource.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/80b8b7e95ca2bacb. Report an issue: GitHub.