laurent22/joplin · warning · Error

Only one output directory can be selected

Error message

Only one output directory can be selected

What it means

Thrown by exportPdf when, in multi-note export mode, the directory picker returns an array with more than one entry. Electron's showOpenDialog can return multiple selected paths; the export logic requires exactly one output directory.

Source

Thrown at packages/app-desktop/gui/WindowCommandsAndDialogs/commands/exportPdf.ts:36

				noteIds = noteIds || context.state.selectedNoteIds;

				if (!noteIds.length) throw new Error('No notes selected for pdf export');

				let path = null;
				if (noteIds.length === 1) {
					path = await bridge().showSaveDialog({
						filters: [{ name: _('PDF File'), extensions: ['pdf'] }],
						defaultPath: await InteropServiceHelper.defaultFilename(noteIds[0], 'pdf'),
					});
				} else {
					path = await bridge().showOpenDialog({
						properties: ['openDirectory', 'createDirectory'],
					});
				}

				if (Array.isArray(path)) {
					if (path.length > 1) {
						throw new Error('Only one output directory can be selected');
					}

					path = path[0];
				}

				if (!path) return;

				for (let i = 0; i < noteIds.length; i++) {
					const note = await Note.load(noteIds[i]);

					let pdfPath = '';

					if (noteIds.length === 1) {
						pdfPath = path;
					} else {
						const n = await InteropServiceHelper.defaultFilename(note.id, 'pdf');
						pdfPath = await shim.fsDriver().findUniqueFilename(`${path}/${n}`);
					}

View on GitHub (pinned to 2654b33620)

Solutions

  1. Select a single directory in the picker dialog.
  2. Restrict showOpenDialog properties to disallow multi-selection (remove 'multiSelections' if present).
  3. Take the first entry (path[0]) instead of throwing if multi-select is not intended to be an error.
  4. Pre-validate the returned array length and re-prompt the user.

Example fix

// before
if (path.length > 1) {
  throw new Error('Only one output directory can be selected');
}

// after — coerce to first selection with a notice
if (path.length > 1) {
  path = path[0];
  bridge().showInfoMessageBox(_('Using the first selected directory: %s', path));
}
Defensive patterns

Strategy: validation

Validate before calling

if (Array.isArray(path) && path.length > 1) {
  // either take the first, or re-prompt the user for a single directory
  path = path[0];
}
// proceed with a single path

Type guard

function isSingleDirectory(path: string | string[] | null): path is string {
  return typeof path === 'string' || (Array.isArray(path) && path.length === 1);
}

Try / catch

try {
  await exportRuntime.execute(ctx, noteIds);
} catch (e) {
  if (e.message === 'Only one output directory can be selected') {
    // re-open the dialog with multiSelection disabled
  } else throw e;
}

Prevention

When it happens

Trigger: Exporting 2+ notes to PDF; showOpenDialog({properties:['openDirectory', ...]}) returns an array of length > 1 (user multi-selected directories), triggering the `path.length > 1` guard.

Common situations: The user Ctrl/Cmd-clicks multiple folders in the directory picker; the dialog properties allow multiSelection inadvertently; an automated harness passes multiple directory paths.

Related errors


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