{"record":{"id":"82695a0a30255b22","repo":"windmill-labs/windmill","slug":"could-not-read-what-is-already-at-path-e-bo","errorCode":null,"errorMessage":"Could not read what is already at ${path} (${e?.body ?? e?.message ?? e}), so it will not be written over. Try again.","messagePattern":"Could not read what is already at (.+?) \\((.+?)\\), so it will not be written over\\. Try again\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/AppConnectInner.svelte","lineNumber":776,"sourceCode":"\t\t\t// The type is checked here and not only by the caller: `fillPath` says \"write into\n\t\t\t// this path\", and a path says nothing about what lives at it. A workspace resource\n\t\t\t// of another type sitting where the project wanted one of ours would otherwise have\n\t\t\t// its value replaced with credentials for a different provider, while keeping its\n\t\t\t// own type — destroying a working resource that has nothing to do with the import.\n\t\t\tconst filling = exists && !!fillPath && path === fillPath\n\t\t\tif (filling) {\n\t\t\t\t// Fails closed. Only a read that succeeds and answers with exactly this type\n\t\t\t\t// permits the write — a failed read, a missing type, or any other type all\n\t\t\t\t// refuse. Letting \"could not tell\" through is how the overwrite this guard\n\t\t\t\t// exists to stop would happen anyway, on the one occasion the check was needed\n\t\t\t\t// and could not run.\n\t\t\t\tlet occupantType: string | undefined\n\t\t\t\ttry {\n\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","sourceCodeStart":758,"sourceCodeEnd":794,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/AppConnectInner.svelte#L758-L794","documentation":"In the app OAuth connect flow (AppConnectInner.svelte `next`), before writing a resource at the user-chosen path, Windmill reads the existing resource to check whether the path is already occupied. If `ResourceService.getResource` throws (network error, 404-with-error, permission denial, malformed body), the code cannot verify what is there and refuses to overwrite, throwing this error with the underlying message embedded.","triggerScenarios":"User submits the connect form with a path whose GET /resources lookup fails: backend unreachable, insufficient permissions on the target path, or the resource API returns a non-JSON error body that the client cannot parse.","commonSituations":"Running the frontend against a stale REMOTE/backend port (proxy 502s), a restricted token that cannot read the workspace resource, or a workspace name typo in effectiveWorkspace so the read 404s with an error body.","solutions":["Check the embedded inner message: fix the underlying cause (restart backend on the right port, verify REMOTE matches the backend port)","Confirm you are logged into the correct workspace and your token has resource read permission","Retry the flow — the message is explicitly a 'try again' guard against blind overwrite","Manually inspect the path in the resource list and delete it if it exists before retrying"],"exampleFix":"// before: error swallowed by throw, retry loop absent\ntry { await connectNext() } catch (e) { console.error(e) }\n// after: surface and retry once after connectivity check\ntry {\n  await assertBackendReachable();\n  await connectNext();\n} catch (e) {\n  if (/Could not read what is already at/.test(String(e))) await retryConnectNext();\n  else console.error(e);\n}","handlingStrategy":"try-catch","validationCode":"// before connecting\nconst res = await fetch(`${backendUrl}/api/w/${workspace}/resources/get/${encodeURIComponent(path)}`);\nif (!res.ok) throw new Error(`Cannot verify path ${path}: ${res.status}; refusing to proceed`);","typeGuard":"function isReadableResource(r: unknown): r is { resource_type: string } {\n  return !!r && typeof r === 'object' && typeof (r as any).resource_type === 'string';\n}","tryCatchPattern":"try {\n  await connectNext();\n} catch (e) {\n  if (/Could not read what is already at/.test(String(e))) {\n    const cause = String(e).match(/\\((.+)\\)/)?.[1];\n    console.warn('Path verification failed:', cause); // retry or re-auth\n  } else throw e;\n}","preventionTips":["Verify backend connectivity (correct REMOTE/port) before running connect flows","Ensure your token has resource read permissions in the target workspace","Inspect the path in the resource list before importing","Retry rather than force-write when path verification fails"],"tags":["oauth","network","resource","frontend"],"backgroundTag":"resource-read-failed","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"}