windmill-labs/windmill · error

Variable at path ${varPath} already exists. Delete it or pic

Error message

Variable at path ${varPath} already exists. Delete it or pick another path

What it means

When the OAuth flow handles multiple linked secret fields (e.g. client_id + client_secret stored as separate variables), it derives a per-field path `<path>_<secretField>` and checks each for an existing variable. If any derived per-field variable path is taken, it throws "Variable at path <varPath> already exists. Delete it or pick another path". Same uniqueness rule as the single-path case, applied per secret field.

Source

Thrown at frontend/src/lib/components/AppConnectInner.svelte:744

			}
			// Check if variable paths already exist
			if (!manual || linkedSecrets.length <= 1) {
				const exists = await VariableService.existsVariable({
					workspace: effectiveWorkspace,
					path
				})
				if (exists) {
					throw Error(`Variable at path ${path} already exists. Delete it or pick another path`)
				}
			} else {
				for (const secretField of linkedSecrets) {
					const varPath = `${path}_${secretField}`
					const exists = await VariableService.existsVariable({
						workspace: effectiveWorkspace,
						path: varPath
					})
					if (exists) {
						throw Error(
							`Variable at path ${varPath} already exists. Delete it or pick another path`
						)
					}
				}
			}
			let exists = await ResourceService.existsResource({
				workspace: effectiveWorkspace,
				path
			})

			// Filling one names its path up front; anything else reaching an occupied path got
			// there by the user typing it, which is the case worth refusing.
			//
			// The type is checked here and not only by the caller: `fillPath` says "write into
			// this path", and a path says nothing about what lives at it. A workspace resource
			// of another type sitting where the project wanted one of ours would otherwise have
			// its value replaced with credentials for a different provider, while keeping its
			// own type — destroying a working resource that has nothing to do with the import.

View on GitHub (pinned to e474e8803c)

Solutions

  1. Change the base path in the dialog — all derived `<path>_<field>` variables must be free.
  2. Delete the conflicting `<path>_<secretField>` variable(s) listed in the message if they are stale.
  3. Reuse the existing variables by pointing the resource at them instead of re-running creation.
  4. Pre-check all derived paths before starting the flow (see validationCode) and resolve collisions up front.

Example fix

// before: 'acme_oauth_secret' already exists, blocking creation
path = 'acme_oauth'; // derives acme_oauth_client_id / acme_oauth_client_secret
await next();

// after: pre-check every derived path
const fields = ['client_id', 'client_secret'];
for (const f of fields) {
  const p = `${path}_${f}`;
  if (await VariableService.existsVariable({ workspace, path: p })) throw new Error(`pick another base path: ${p} taken`);
}
await next();
Defensive patterns

Strategy: validation

Validate before calling

// check every derived per-field path before running the flow
for (const field of linkedSecrets) {
  const varPath = `${path}_${field}`;
  if (await VariableService.existsVariable({ workspace, path: varPath })) {
    throw new Error(`base path '${path}' collides via ${varPath}; pick another`);
  }
}

Try / catch

try {
  await next();
} catch (e) {
  if (e instanceof Error && /already exists/.test(e.message)) {
    const varPath = e.message.match(/path (\S+) already/)?.[1];
    // delete or rename that specific <base>_<field> variable, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `next()` when `manual == true` and `linkedSecrets.length > 1`: the loop over `linkedSecrets` builds `${path}_${secretField}` for each field and one of the `existsVariable` checks returns true.

Common situations: Partial completion of a previous multi-secret connect attempt (first variable created, second collided); base path chosen to collide with another app's suffixed variables; re-connecting an app where `<path>_client_secret` already exists from an earlier config.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/5270064d4531b8b4. Report an issue: GitHub.