{"record":{"id":"b12d92edb5b82816","repo":"windmill-labs/windmill","slug":"resource-at-path-path-already-exists-delete-it","errorCode":null,"errorMessage":"Resource at path ${path} already exists. Delete it or pick another path","messagePattern":"Resource at path (.+?) already exists\\. Delete it or pick another path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/AppConnectInner.svelte","lineNumber":790,"sourceCode":"\t\t\t\t\toccupantType = (\n\t\t\t\t\t\tawait ResourceService.getResource({ workspace: effectiveWorkspace, path })\n\t\t\t\t\t)?.resource_type\n\t\t\t\t} catch (e: any) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Could not read what is already at ${path} (${e?.body ?? e?.message ?? e}), ` +\n\t\t\t\t\t\t\t`so it will not be written over. Try again.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (occupantType !== resourceType) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Resource at path ${path} is ${\n\t\t\t\t\t\t\toccupantType ? `a ${occupantType} resource` : 'of an unknown type'\n\t\t\t\t\t\t}, not ${resourceType}. Move or rename it, then import again.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (exists && !filling) {\n\t\t\t\tthrow Error(`Resource at path ${path} already exists. Delete it or pick another path`)\n\t\t\t}\n\n\t\t\t// Per-instance OAuth providers (Snowflake, ServiceNow, …): fill the\n\t\t\t// resource args from the connection's instance, per the registry\n\t\t\t// template's resource_mapping (e.g. ServiceNow -> instance_url:\n\t\t\t// https://{instance}.service-now.com). Bring-your-own carries the instance\n\t\t\t// the user entered in `ccInstance` (raw, possibly a full host); the shared\n\t\t\t// path carries it (already normalized) in the connect entry's extra_params.\n\t\t\t// Prefer the user-entered one so the saved resource matches the exchange.\n\t\t\tconst connectTemplate = registryEntryFor(resourceType)?.connect_config_template\n\t\t\tif (connectTemplate?.resource_mapping) {\n\t\t\t\tconst instanceKey = connectTemplate.extra_params_key ?? 'instance'\n\t\t\t\tlet instanceValue = extra_params.find(([key, _]) => key === instanceKey)?.[1] ?? ''\n\t\t\t\tif (ccInstance.trim()) {\n\t\t\t\t\tconst stripSuffix = connectTemplate.strip_suffix as string | undefined\n\t\t\t\t\tlet v = ccInstance\n\t\t\t\t\t\t.trim()\n\t\t\t\t\t\t.replace(/^https?:\\/\\//, '')","sourceCodeStart":772,"sourceCodeEnd":808,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/AppConnectInner.svelte#L772-L808","documentation":"In `next` (AppConnectInner.svelte), when the connect dialog is not in 'filling' mode (i.e. it is creating/importing fresh rather than filling an existing resource) and the chosen path already exists, Windmill refuses to proceed to avoid silently overwriting an existing resource.","triggerScenarios":"Submitting the connect form with a path that resolves to an existing resource while the flow is in create/import mode rather than re-fill mode.","commonSituations":"Re-running the OAuth import after a previous successful save, a user re-typing a previously used path, or switching workspaces where a same-named resource already exists.","solutions":["Delete the existing resource at that path if it is obsolete, then retry","Choose a different path in the dialog","Enter the edit/fill flow for the existing resource instead of import","Use the resource edit UI to update credentials in place rather than re-importing"],"exampleFix":"// before: blind re-import to same path\nawait connectNext();\n// after: clear stale resource or pick a fresh path\nif (await resourceExists(workspace, path)) await ResourceService.deleteResource({ workspace, path });\nawait connectNext();","handlingStrategy":"validation","validationCode":"const occupant = await ResourceService.getResource({ workspace, path }).catch(() => null);\nif (occupant) throw new Error(`Path ${path} already exists — pick another or delete first`);","typeGuard":null,"tryCatchPattern":"try { await connectNext(); } catch (e) {\n  if (/already exists\\. Delete it or pick another path/.test(String(e))) {\n    path = suggestAlternativePath(path); // or delete stale resource\n    await connectNext();\n  } else throw e;\n}","preventionTips":["Check the resource list before re-importing to the same path","Adopt path conventions that include a version or timestamp when importing repeatedly","Use the edit/fill flow instead of import for existing resources"],"tags":["oauth","resource","conflict","frontend"],"backgroundTag":"resource-path-conflict","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}