{"record":{"id":"8499c77cf85db925","repo":"supabase/supabase","slug":"snippet-named-updates-name-foundsnippet-name","errorCode":null,"errorMessage":"Snippet named \"${updates.name ?? foundSnippet.name}\" already exists in the specified folder","messagePattern":"Snippet named \"(.+?)\" already exists in the specified folder","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/studio/lib/api/snippets.utils.ts","lineNumber":421,"sourceCode":"      (entry): entry is FilesystemEntry & { type: 'file'; content: string } => entry.type === 'file'\n    )\n    .find((s) => s.id === id)\n\n  if (!foundSnippet) {\n    throw new Error(`Snippet with id ${id} not found`)\n  }\n\n  const newId = generateDeterministicUuid([\n    updates.folder_id !== undefined ? updates.folder_id : foundSnippet.folderId,\n    `${updates.name ?? foundSnippet.name}.sql`,\n  ])\n\n  const snippetAtTargetLocation = entries.find(\n    (entry) => entry.id === newId && entry.type === 'file'\n  )\n\n  if (snippetAtTargetLocation && snippetAtTargetLocation.id !== foundSnippet.id) {\n    throw new Error(\n      `Snippet named \"${updates.name ?? foundSnippet.name}\" already exists in the specified folder`\n    )\n  }\n\n  const snippet = buildSnippet(\n    foundSnippet.name,\n    foundSnippet.content || '',\n    foundSnippet.folderId,\n    foundSnippet.createdAt\n  )\n\n  // it's easier to delete the old file first and then recreate a new one\n  await deleteSnippet(snippet.id)\n\n  const updatedSnippet = await saveSnippet({\n    name: updates.name ?? snippet.name,\n    content: updates.content ?? snippet.content,\n    // folder_id can be null","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/supabase/supabase/blob/beee91b9c2228dd57302dec75c733baaa84ab543/apps/studio/lib/api/snippets.utils.ts#L403-L439","documentation":"updateSnippet computes the target deterministic id from the (new folder_id, new name) and checks whether a different file already occupies that slot. If so — e.g. renaming 'a.sql' to 'b.sql' when 'b.sql' exists — it refuses the overwrite. This prevents data loss from a rename/move onto an existing file.","triggerScenarios":"A PATCH /content/:id that changes name and/or folder_id such that the resulting path collides with another existing snippet in the same folder. Two snippets cannot share a filename.","commonSituations":"User renames a snippet to a name already in use; user moves a snippet into a folder containing a same-named snippet; bulk rename creates a collision.","solutions":["Before applying, check the target folder for a name clash and prompt the user to overwrite or pick a new name.","If overwrite is intended, delete the target snippet first, then update.","Catch the error and return 409 Conflict with the colliding name so the client can react."],"exampleFix":"// before\nawait updateSnippet(id, { name: newName })\n\n// after\nconst targetId = generateDeterministicUuid([folderId, `${newName}.sql`])\nconst clash = (await getFilesystemEntries()).find(e => e.id === targetId && e.type === 'file')\nif (clash && clash.id !== id) {\n  throw new HttpError(409, `A snippet named ${newName} already exists there`)\n}\nawait updateSnippet(id, { name: newName })","handlingStrategy":"validation","validationCode":"import { generateDeterministicUuid } from './snippets.browser'\nconst targetId = generateDeterministicUuid([\n  updates.folder_id ?? foundSnippet.folderId,\n  `${updates.name ?? foundSnippet.name}.sql`,\n])\nconst clash = (await getFilesystemEntries({ includeContent: false }))\n  .find(e => e.id === targetId && e.type === 'file' && e.id !== id)\nif (clash) throw new Error('Target name already in use')","typeGuard":"const hasNameClash = async (folderId: string | null, name: string, exceptId: string): Promise<boolean> => {\n  const targetId = generateDeterministicUuid([folderId, `${name}.sql`])\n  return (await getFilesystemEntries({ includeContent: false }))\n    .some(e => e.id === targetId && e.type === 'file' && e.id !== exceptId)\n}","tryCatchPattern":"try {\n  await updateSnippet(id, { name: newName })\n} catch (e) {\n  if (e instanceof Error && e.message.includes('already exists in the specified folder')) {\n    return res.status(409).json({ error: { message: 'A snippet with that name already exists there' } })\n  }\n  throw e\n}","preventionTips":["Pre-check the target folder for a name clash before applying a rename/move.","Prompt the user to overwrite or pick a new name when a clash exists.","Return 409 at the route boundary for collisions."],"tags":["snippets","conflict","validation","filesystem","self-hosted"],"backgroundTag":null,"analyzedSha":"beee91b9c2228dd57302dec75c733baaa84ab543","analyzedAt":"2026-08-12T06:51:48.935Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}