laurent22/joplin · error · Error

Could not create directory: ${path}

Error message

Could not create directory: ${path}

What it means

Thrown by the Node fs driver's mkdir(). The underlying fs-extra mkdirp() does not error if directory creation silently fails, so the driver explicitly re-checks existence afterward. If the dir still isn't there, it throws to prevent the synchronizer from proceeding against a non-existent path (the historical bug laurent22/joplin#2117).

Source

Thrown at packages/lib/fs-driver-node.ts:91

				}
				throw this.fsErrorToJsError_(error);
			}
		}

		throw lastError;
	}

	public exists(path: string) {
		return fs.pathExists(path);
	}

	public async mkdir(path: string) {
		// Note that mkdirp() does not throw an error if the directory
		// could not be created. This would make the synchroniser to
		// incorrectly try to sync with a non-existing dir:
		// https://github.com/laurent22/joplin/issues/2117
		const r = await fs.mkdirp(path);
		if (!(await this.exists(path))) throw new Error(`Could not create directory: ${path}`);
		return r;
	}

	public async stat(path: string): Promise<Stat> {
		try {
			const stat = await fs.stat(path);
			return {
				birthtime: stat.birthtime,
				mtime: stat.mtime,
				isDirectory: () => stat.isDirectory(),
				path: path,
				size: stat.size,
			};
		} catch (error) {
			if (error.code === 'ENOENT') return null;
			throw error;
		}
	}

View on GitHub (pinned to 2654b33620)

Solutions

  1. Check filesystem permissions on the parent and target path; grant write access.
  2. Confirm no regular file occupies the target path (stat it first).
  3. Free disk space / raise quota on the volume.
  4. On Windows, ensure the path has no invalid characters (<>:"|?*).
  5. Verify the volume is mounted and writable.

Example fix

// before
await shim.fsDriver().mkdir(targetDir);
// after - diagnose the silent mkdirp failure
if (await shim.fsDriver().exists(targetDir)) return;
try { await shim.fsDriver().mkdir(targetDir); }
catch (e) {
  const parent = path.dirname(targetDir);
  if (!(await shim.fsDriver().exists(parent))) throw new Error(`Parent missing: ${parent}`);
  throw e;
}
Defensive patterns

Strategy: validation

Validate before calling

if (await shim.fsDriver().exists(targetDir)) return;
const parent = path.dirname(targetDir);
if (!(await shim.fsDriver().exists(parent))) throw new Error(`Parent directory missing: ${parent}`);
if (!(await shim.fsDriver().isWritable(parent))) throw new Error(`Parent not writable: ${parent}`);

Type guard

function isMkdirFailed(e: any): boolean {
  return e && typeof e.message === 'string' && e.message.startsWith('Could not create directory:');
}

Try / catch

try {
  await shim.fsDriver().mkdir(targetDir);
} catch (e) {
  if (isMkdirFailed(e)) {
    throw new Error(`Cannot create directory ${targetDir}; check permissions, disk space, and that no file blocks the path.`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling mkdir() where the parent is read-only, the disk is full, the path is invalid, or a file occupies the target path. mkdirp reports success but exists() returns false.

Common situations: Insufficient filesystem permissions; read-only mount; path component is a file not a directory; disk full or quota exceeded; network share dropped mid-operation; invalid characters in the path on Windows; antivirus blocking directory creation.

Related errors


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