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
- Change the base path in the dialog — all derived `<path>_<field>` variables must be free.
- Delete the conflicting `<path>_<secretField>` variable(s) listed in the message if they are stale.
- Reuse the existing variables by pointing the resource at them instead of re-running creation.
- 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
- Pre-check all `<base>_<secretField>` paths for every linked secret before advancing.
- Choose base paths unlikely to collide (include app + environment in the name).
- Remove leftover variables from partially completed connect attempts.
- Reuse existing per-field variables instead of re-creating when reconnecting an app.
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
- Variable at path ${path} already exists. Delete it or pick a
- Path is not set
- Could not read what is already at ${path} (${e?.body ?? e?.m
- Resource at path ${path} is ${occupantType ? `a ${occupantTy
- Resource at path ${path} already exists. Delete it or pick a
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/5270064d4531b8b4.
Report an issue: GitHub.