{"record":{"id":"9368bcf3b966e6cd","repo":"phacility/phabricator","slug":"document-already-exists","errorCode":null,"errorMessage":"Document already exists!","messagePattern":"Document already exists!","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php","lineNumber":42,"sourceCode":"  }\n\n  protected function execute(ConduitAPIRequest $request) {\n    $slug = $request->getValue('slug');\n    if ($slug === null || !strlen($slug)) {\n      throw new Exception(pht('Field \"slug\" must be non-empty.'));\n    }\n\n    $doc = id(new PhrictionDocumentQuery())\n      ->setViewer($request->getUser())\n      ->withSlugs(array(PhabricatorSlug::normalize($slug)))\n      ->requireCapabilities(\n        array(\n          PhabricatorPolicyCapability::CAN_VIEW,\n          PhabricatorPolicyCapability::CAN_EDIT,\n        ))\n      ->executeOne();\n    if ($doc) {\n      throw new Exception(pht('Document already exists!'));\n    }\n\n    $doc = PhrictionDocument::initializeNewDocument(\n      $request->getUser(),\n      $slug);\n\n    $xactions = array();\n    $xactions[] = id(new PhrictionTransaction())\n      ->setTransactionType(PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)\n      ->setNewValue($request->getValue('title'));\n    $xactions[] = id(new PhrictionTransaction())\n      ->setTransactionType(PhrictionDocumentContentTransaction::TRANSACTIONTYPE)\n      ->setNewValue($request->getValue('content'));\n\n    $editor = id(new PhrictionTransactionEditor())\n      ->setActor($request->getUser())\n      ->setContentSource($request->newContentSource())\n      ->setContinueOnNoEffect(true)","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php#L24-L60","documentation":"phriction.create initializes a brand-new wiki document, and document paths are unique. It first queries by the normalized slug (with view and edit capabilities required) and refuses with this error when a document already occupies the path. Nothing is written; the call aborts before any transaction is applied.","triggerScenarios":"Calling phriction.create with a slug whose normalized form matches an existing document, including when the existing document differs only in raw spelling (case, trailing slash, whitespace) that normalizes to the same path.","commonSituations":"Retry scripts that re-run create after partial failures; multiple tools creating the same page; slug normalization surprises where 'My Page' and 'my-page' collide.","solutions":["Switch to phriction.edit on the existing slug to update the document","Choose a different slug for the new document","If the existing document was deleted, restore or edit it rather than recreating over the path"],"exampleFix":"// before: create fails once the path is taken\n$client->callMethodSynchronous('phriction.create', array(\n  'slug' => '/runbook/deploy',\n  'title' => $title,\n  'content' => $content,\n));\n\n// after: create once, then edit the existing document\n$client->callMethodSynchronous('phriction.edit', array(\n  'slug' => '/runbook/deploy',\n  'title' => $title,\n  'content' => $content,\n));","handlingStrategy":"fallback","validationCode":"// Pre-check the path, then create only when it is free.\n$existing = id(new PhrictionDocumentQuery())\n  ->setViewer($viewer)\n  ->withSlugs(array(PhabricatorSlug::normalize($slug)))\n  ->executeOne();\nif ($existing) {\n  // route to phriction.edit instead of phriction.create\n}","typeGuard":null,"tryCatchPattern":"try {\n  $result = $client->callMethodSynchronous('phriction.create', $params);\n} catch (Exception $ex) {\n  if (strpos($ex->getMessage(), 'Document already exists') !== false) {\n    $result = $client->callMethodSynchronous('phriction.edit', $params);\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Make create-then-edit idempotent in scripts that may re-run","Pre-check slug availability when the path is user-chosen","Normalize slugs before comparing so spelling variants do not sneak past the pre-check"],"tags":["phabricator","phriction","conduit","slug","duplicate","uniqueness"],"backgroundTag":"duplicate-record","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}