laurent22/joplin · info · JoplinError

404

404

Error message

The specified file doesn't exist.

What it means

Synthesized by the WebDAV driver's get(): Microsoft IIS (and some other servers) respond to GET of a missing file with HTTP 200 and a body literally reading "The specified file doesn't exist." instead of the correct 404. The driver detects that exact body and throws a JoplinError with code 404 so the caller's not-found handling triggers normally.

Source

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

		});

		return {
			items: stats,
			hasMore: false,
			context: null,
		};
	}

	async get(path, options) {
		if (!options) options = {};
		if (!options.responseFormat) options.responseFormat = 'text';
		try {
			const response = await this.api().exec('GET', path, null, null, options);

			// This is awful but instead of a 404 Not Found, Microsoft IIS returns an HTTP code 200
			// with a response body "The specified file doesn't exist." for non-existing files,
			// so we need to check for this.
			if (response === 'The specified file doesn\'t exist.') throw new JoplinError(response, 404);
			return response;
		} catch (error) {
			if (error.code !== 404) throw error;
			return null;
		}
	}

	async mkdir(path) {
		try {
			// RFC wants this, and so does NGINX. Not having the trailing slash means that some
			// WebDAV implementations will redirect to a URL with "/". However, when doing so
			// in React Native, the auth headers, etc. are lost so we need to avoid this.
			// https://github.com/facebook/react-native/issues/929
			if (!path.endsWith('/')) path = `${path}/`;
			await this.api().exec('MKCOL', path);
		} catch (error) {
			if (error.code === 405) return; // 405 means that the collection already exists (Method Not Allowed)

View on GitHub (pinned to 2654b33620)

Solutions

  1. No action needed if you're a normal caller — get() returns null for missing files; this error is internal and already handled.
  2. If you see it propagate, configure IIS to return standard HTTP 404 instead of a 200 with an error body (disable custom error pages / HTTP errors for the WebDAV site).
  3. Upgrade the WebDAV server module; newer IIS WebDAV implementations return correct status codes.
  4. Switch to a more standards-compliant WebDAV server.

Example fix

// This is a workaround for non-standards-compliant servers; callers already get null.
// To remove the need for the workaround server-side, configure IIS:
//   <httpErrors errorMode="Detailed" existingResponse="PassThrough" />
// so missing files return 404 instead of 200 + body.
Defensive patterns

Strategy: try-catch

Type guard

function isIisMissingFileBody(body: any): boolean {
  return typeof body === 'string' && body === "The specified file doesn't exist.";
}

Try / catch

// Already handled internally - get() returns null for missing files.
const data = await driver.get(path);
if (data === null) { /* file does not exist - normal not-found path */ }

Prevention

When it happens

Trigger: Calling get() for a path that doesn't exist on an IIS-backed WebDAV server. The driver converts the non-standard 200 body into a 404 JoplinError, which the surrounding try/catch then maps to a null return.

Common situations: Syncing against an IIS WebDAV target where a note/resource was deleted remotely; first-time sync probing for files that haven't been created yet; IIS configured to return friendly error pages instead of proper status codes.

Related errors


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