{"record":{"id":"a70d29722d1d2b52","repo":"phacility/phabricator","slug":"service-s-is-unrecognized-restricted-or-you-d","errorCode":null,"errorMessage":"Service \"%s\" is unrecognized, restricted, or you do not have permission to edit it.","messagePattern":"Service \"(.+?)\" is unrecognized, restricted, or you do not have permission to edit it\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/almanac/editor/AlmanacBindingEditEngine.php","lineNumber":81,"sourceCode":"\n    if ($service_phid === null) {\n      throw new Exception(\n        pht(\n          'When creating a new Almanac binding via the Conduit API, you '.\n          'must provide a \"service\" transaction to select a service to bind.'));\n    }\n\n    $service = id(new AlmanacServiceQuery())\n      ->setViewer($this->getViewer())\n      ->withPHIDs(array($service_phid))\n      ->requireCapabilities(\n        array(\n          PhabricatorPolicyCapability::CAN_VIEW,\n          PhabricatorPolicyCapability::CAN_EDIT,\n        ))\n      ->executeOne();\n    if (!$service) {\n      throw new Exception(\n        pht(\n          'Service \"%s\" is unrecognized, restricted, or you do not have '.\n          'permission to edit it.',\n          $service_phid));\n    }\n\n    $this->setService($service);\n\n    return $this->newEditableObject();\n  }\n\n  protected function newObjectQuery() {\n    return id(new AlmanacBindingQuery())\n      ->needProperties(true);\n  }\n\n  protected function getObjectCreateTitleText($object) {\n    return pht('Create Binding');","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/almanac/editor/AlmanacBindingEditEngine.php#L63-L99","documentation":"Thrown by PhabricatorRepository::assertValidRepositorySlug() when validating a repository short name (slug) that is the empty string. The slug becomes the canonical 'rh.../shortname' clone URI component, so an empty value is structurally invalid. The assertion runs when a short-name transaction sets the value (PhabricatorRepositorySlugTransaction), e.g. via the UI or the 'repository.edit' Conduit method, and is wrapped by isValidRepositorySlug() for non-throwing checks.","triggerScenarios":"Applying a repository.edit transaction that sets 'slug' (short name) to '' — e.g. building transactions in a script where the slug variable is empty: PhabricatorRepositorySlugTransaction.php:62 calls assertValidRepositorySlug('') and the !strlen($slug) guard at PhabricatorRepository.php:371 throws.","commonSituations":"Automation scripts that always send a 'set slug' transaction even when no short name is configured, sending an empty string; UI forms submitting before the short-name field is filled; migrating repositories where the callsign-to-slug conversion produced '' (the storage layer falls back to the callsign elsewhere, but an explicit empty transaction still fails).","solutions":["Omit the short-name transaction entirely when no short name is wanted, instead of sending an empty value.","Populate the slug field with a valid name (letters, numbers, periods, hyphens, underscores, 1-64 chars).","Guard scripts with PhabricatorRepository::isValidRepositorySlug($slug) before applying the transaction."],"exampleFix":"// before\n$transactions[] = id(new PhabricatorRepositoryTransaction())\n  ->setTransactionType(PhabricatorRepositorySlugTransaction::TRANSACTIONTYPE)\n  ->setNewValue($slug); // $slug == ''\n\n// after\nif (strlen($slug)) {\n  $transactions[] = id(new PhabricatorRepositoryTransaction())\n    ->setTransactionType(PhabricatorRepositorySlugTransaction::TRANSACTIONTYPE)\n    ->setNewValue($slug);\n}","handlingStrategy":"type-guard","validationCode":"if (!strlen($slug)) { /* skip the short-name transaction entirely */ }","typeGuard":"function isValidShortName($slug) {\n  return PhabricatorRepository::isValidRepositorySlug((string)$slug);\n}","tryCatchPattern":"try {\n  PhabricatorRepository::assertValidRepositorySlug($slug);\n} catch (Exception $ex) {\n  // show $ex->getMessage() next to the form field / in the Conduit error\n}","preventionTips":["Only append a slug transaction when the value is non-empty.","Run isValidRepositorySlug() in provisioning scripts before applying edits."],"tags":["phabricator","php","validation","repository-shortname","conduit"],"backgroundTag":"empty-string-validation","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}