{"record":{"id":"6ca91583c67de2e5","repo":"hcengineering/platform","slug":"document-documentname-already-exists","errorCode":null,"errorMessage":"Document ${documentName} already exists","messagePattern":"Document (.+?) already exists","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/collaborator/src/rpc/methods/createContent.ts","lineNumber":37,"sourceCode":"  decodeDocumentId\n} from '@hcengineering/collaborator-client'\nimport { saveCollabJson } from '@hcengineering/collaboration'\nimport { type Blob, type Ref, MeasureContext } from '@hcengineering/core'\nimport { Context } from '../../context'\nimport { RpcMethodParams } from '../rpc'\n\nexport async function createContent (\n  ctx: MeasureContext,\n  context: Context,\n  documentName: string,\n  payload: CreateContentRequest,\n  params: RpcMethodParams\n): Promise<CreateContentResponse> {\n  const { content } = payload\n  const { hocuspocus, storageAdapter } = params\n\n  if (hocuspocus.documents.has(documentName) || hocuspocus.loadingDocuments.has(documentName)) {\n    throw new Error(`Document ${documentName} already exists`)\n  }\n\n  const { documentId } = decodeDocumentId(documentName)\n\n  const result: Record<string, Ref<Blob>> = {}\n  for (const [field, markup] of Object.entries(content)) {\n    const blob = await saveCollabJson(ctx, storageAdapter, context.wsIds, documentId, markup)\n    result[field] = blob\n  }\n\n  return { content: result }\n}\n","sourceCodeStart":19,"sourceCodeEnd":50,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/collaborator/src/rpc/methods/createContent.ts#L19-L50","documentation":"The createContent RPC checks hocuspocus.documents and hocuspocus.loadingDocuments before creating a new document. If a document with the same name is already loaded (or currently being loaded), it throws this error to prevent duplicate in-memory documents. The RPC is intended for creating documents that don't yet exist server-side.","triggerScenarios":"Calling the createContent RPC with a documentName that is already open in the Hocuspocus server (an active collaboration session) or is mid-load; concurrent createContent calls for the same document; or a client creating content for a document it already has a provider connected to.","commonSituations":"Double-click/double-submit on a 'create' button, retry logic re-issuing createContent after a slow first response, frontend opening the doc before the create RPC completes, or reusing a document name across create calls.","solutions":["Treat this as a success/no-op if the existing document is yours: catch the error and proceed to connect instead of creating.","Check client-side whether the document already exists (or is open) before calling createContent.","Debounce/guard create RPCs so concurrent/duplicate requests aren't sent for the same documentName.","Use a unique documentName (new document id) if a genuinely new document is intended."],"exampleFix":"// before\nawait rpc.createContent({ documentName, content })\nconnectProvider(documentName)\n\n// after\ntry {\n  await rpc.createContent({ documentName, content })\n} catch (e) {\n  if (!String(e.message).includes('already exists')) throw e\n}\nconnectProvider(documentName)","handlingStrategy":"try-catch","validationCode":"// server-side pre-check before RPC\nif (hocuspocus.documents.has(documentName) || hocuspocus.loadingDocuments.has(documentName)) {\n  return existingDocumentState // skip create\n}\n// client-side pre-check: don't create for a doc already open\nif (openProviders.has(documentName)) return","typeGuard":null,"tryCatchPattern":"try {\n  await rpc.createContent({ documentName, content })\n} catch (err) {\n  if (String(err.message).includes('already exists')) {\n    // idempotent: document is already available, just connect\n    return\n  }\n  throw err\n}","preventionTips":["Make create calls idempotent: catch 'already exists' and treat as success.","Debounce/deduplicate create RPCs for the same documentName in the client.","Don't call createContent for documents already open in a provider session.","Generate fresh unique document ids when a genuinely new document is needed."],"tags":["rpc","duplicate","collaboration","concurrency"],"backgroundTag":"document-already-exists","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}