n8n-io/n8n · error · UserError

Can't migrate workflows and credentials to the project with

Error message

Can't migrate workflows and credentials to the project with the ID ${flags.projectId}. That project is a personal project belonging to a user that was created via LDAP and will be deleted as well.

What it means

Thrown by `ldap:reset` when `--projectId` resolves to a personal project belonging to an LDAP-created user. Since LDAP users are deleted in the same run, their personal projects are also removed, so migrating resources there would orphan them. Detected by checking the project ID against `personalProjectIds` returned from `ProjectRelationRepository.getPersonalProjectsForUsers`.

Source

Thrown at packages/cli/src/commands/ldap/reset.ts:91

		const owner = await this.getOwner();
		const ldapIdentities = await Container.get(AuthIdentityRepository).find({
			where: { providerType: 'ldap' },
			select: ['userId'],
		});
		const personalProjectIds = await Container.get(
			ProjectRelationRepository,
		).getPersonalProjectsForUsers(ldapIdentities.map((i) => i.userId));

		// Migrate all workflows and credentials to another project.
		if (flags.projectId ?? flags.userId) {
			if (flags.userId && ldapIdentities.some((i) => i.userId === flags.userId)) {
				throw new UserError(
					`Can't migrate workflows and credentials to the user with the ID ${flags.userId}. That user was created via LDAP and will be deleted as well.`,
				);
			}

			if (flags.projectId && personalProjectIds.includes(flags.projectId)) {
				throw new UserError(
					`Can't migrate workflows and credentials to the project with the ID ${flags.projectId}. That project is a personal project belonging to a user that was created via LDAP and will be deleted as well.`,
				);
			}

			const project = await this.getProject(flags.userId, flags.projectId);

			await Container.get(OwnershipTransferService).transferAllResources(
				personalProjectIds,
				project.id,
			);
		}

		const [ownedSharedWorkflows, ownedSharedCredentials] = await Promise.all([
			Container.get(SharedWorkflowRepository).find({
				select: { workflowId: true },
				where: { projectId: In(personalProjectIds), role: 'workflow:owner' },
			}),
			Container.get(SharedCredentialsRepository).find({

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Target an existing shared/team project instead of a personal project.
  2. Create a new shared project and pass its ID via `--projectId`.
  3. Fall back to `--userId` pointing at a local (non-LDAP) user, or use `--deleteWorkflowsAndCredentials`.

Example fix

// before
n8n ldap:reset --projectId=<personal-project-of-ldap-user>
// after
n8n ldap:reset --projectId=<shared-team-project-id>
Defensive patterns

Strategy: validation

Validate before calling

const personalProjectIds = await projectRelationRepo.getPersonalProjectsForUsers(ldapUserIds);
if (personalProjectIds.includes(targetProjectId)) {
  throw new Error('Target project is a personal project of an LDAP user and will be deleted; pick a shared project.');
}

Prevention

When it happens

Trigger: Passing `--projectId` whose ID is the personal project of an LDAP user; passing a project ID copied from a user's profile page that turns out to be their personal workspace.

Common situations: Operator assumes a project ID is a shared team project when it is actually a personal one; LDAP-only tenancies where every project is a personal project.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/c6e151403cdf95fd. Report an issue: GitHub.