{"record":{"id":"b35298d0ab317aaf","repo":"windmill-labs/windmill","slug":"a-resource-was-created-at-path-while-this-setup","errorCode":null,"errorMessage":"A resource was created at ${path} while this setup was running. Choose another path and try again.","messagePattern":"A resource was created at (.+?) while this setup was running\\. Choose another path and try again\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/workspaceSettings/addDataTableModel.ts","lineNumber":531,"sourceCode":"\t\tdecryptSecret: false\n\t}).catch(() => undefined)\n\treturn held ? (held.edited_at ?? held.edited_by ?? '') : undefined\n}\n\nfunction pathTakenLate(kind: 'variable' | 'resource', path: string): string {\n\treturn `A ${kind} was created at ${path} while this setup was running. Choose another path and try again.`\n}\n\nasync function writeResource(\n\tdeps: RunDeps,\n\tclaims: Claims,\n\tpath: string,\n\tvalue: Record<string, any>,\n\tdescription: string\n): Promise<Claims> {\n\tconst held = await resourceMark(deps, path)\n\tif (held) {\n\t\tif (!stillOurs(claims, 'resource', path, held)) throw new Error(pathTakenLate('resource', path))\n\t\tawait ResourceService.updateResource({\n\t\t\tworkspace: deps.workspace,\n\t\t\tpath,\n\t\t\trequestBody: { value, description }\n\t\t})\n\t} else {\n\t\tawait ResourceService.createResource({\n\t\t\tworkspace: deps.workspace,\n\t\t\trequestBody: { resource_type: 'postgresql', path, value, description }\n\t\t})\n\t}\n\t// Read back rather than claim the username: `created_by` survives an update, so it cannot\n\t// tell an edit by somebody else from no edit at all. `edited_at` moves on every write, which\n\t// is what makes the next attempt able to see one that happened in between.\n\treturn claim(claims, 'resource', path, (await resourceMark(deps, path)) ?? deps.username)\n}\n\n/** `undefined` when nothing is there. */","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/workspaceSettings/addDataTableModel.ts#L513-L549","documentation":"writeResource claims a resource path and, when an existing resource is found, re-verifies via stillOurs that it is still the one this setup claimed before calling ResourceService.updateResource. If the path was taken by someone else during the setup, it throws pathTakenLate('resource', path).","triggerScenarios":"A resource is created at the same path by another admin/session while the add-data-table setup is between its resourceMark claim and the ResourceService.updateResource call.","commonSituations":"Concurrent setup runs by multiple admins; another process or teammate creating the database resource path during a long-running setup wizard.","solutions":["Choose a different resource path and rerun the setup","Delete or rename the conflicting resource and rerun the setup","Run the setup wizard one admin at a time to avoid path collisions"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const existing = await ResourceService.getResource({ workspace, path }).catch(() => null)\nif (existing && !isOurClaim(existing)) console.warn(`Resource '${path}' already exists — choose another path`)","typeGuard":null,"tryCatchPattern":"try {\n  await runSetup(...)\n} catch (e) {\n  if (String(e.message).includes('A resource was created at')) {\n    // prompt for a new resource path and retry the setup\n  }\n}","preventionTips":["Coordinate resource paths across admins before running the setup","Use namespaced resource paths unlikely to collide","Complete setup wizards promptly; long-running setups widen the race window"],"tags":["race-condition","resources","setup-wizard"],"backgroundTag":"concurrent-setup-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"}