{"record":{"id":"9bd36b1aa6043c6f","repo":"phacility/phabricator","slug":"when-creating-a-new-almanac-service-via-the-condui","errorCode":null,"errorMessage":"When creating a new Almanac service via the Conduit API, you must provide a \"type\" transaction to select a type.","messagePattern":"When creating a new Almanac service via the Conduit API, you must provide a \"type\" transaction to select a type\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/almanac/editor/AlmanacServiceEditEngine.php","lineNumber":55,"sourceCode":"  }\n\n  protected function newEditableObject() {\n    $service_type = $this->getServiceType();\n    return AlmanacService::initializeNewService($service_type);\n  }\n\n  protected function newEditableObjectFromConduit(array $raw_xactions) {\n    $type = null;\n    foreach ($raw_xactions as $raw_xaction) {\n      if ($raw_xaction['type'] !== 'type') {\n        continue;\n      }\n\n      $type = $raw_xaction['value'];\n    }\n\n    if ($type === null) {\n      throw new Exception(\n        pht(\n          'When creating a new Almanac service via the Conduit API, you '.\n          'must provide a \"type\" transaction to select a type.'));\n    }\n\n    $map = AlmanacServiceType::getAllServiceTypes();\n    if (!isset($map[$type])) {\n      throw new Exception(\n        pht(\n          'Service type \"%s\" is unrecognized. Valid types are: %s.',\n          $type,\n          implode(', ', array_keys($map))));\n    }\n\n    $this->setServiceType($type);\n\n    return $this->newEditableObject();\n  }","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/almanac/editor/AlmanacServiceEditEngine.php#L37-L73","documentation":"Thrown by PhabricatorRepository::assertValidRepositorySlug() when a repository short name contains multiple consecutive underscores, hyphens, or periods ('__', '--', or '..'). Runs of separators are rejected because '..' enables path-traversal interpretations and repeated separators make URIs ambiguous; Phabricator requires single separators between name words. Enforced by the preg_match('/__|--|\\.\\./', $slug) check in the short-name transaction path.","triggerScenarios":"Setting a short name like 'team--utils' or 'repo..name': the separator-run regex at PhabricatorRepository.php:411 matches and throws with the offending name.","commonSituations":"Naive sanitizers that replace each invalid character individually with '-', turning 'a  b' into 'a--b'; names that literally contain '..' copied from paths; merging prefix and suffix strings that both end/start with a separator.","solutions":["Collapse separator runs to a single character in generated names: preg_replace('/([._-])\\1+/', '$1', $slug) or replace invalid runs with one hyphen ('/[^a-zA-Z0-9._-]+/' with '-').","Fix the source name manually ('team--utils' -> 'team-utils').","Run PhabricatorRepository::isValidRepositorySlug() on generated names before applying them."],"exampleFix":"// before\n$slug = preg_replace('/[^a-zA-Z0-9._-]/', '-', 'team  utils'); // 'team--utils'\n\n// after\n$slug = preg_replace('/[^a-zA-Z0-9._-]+/', '-', 'team  utils'); // 'team-utils'","handlingStrategy":"type-guard","validationCode":"$slug = preg_replace('/([._-]){2,}/', '$1', $slug); // collapse '__', '--', '..'","typeGuard":"function isValidShortName($slug) {\n  return PhabricatorRepository::isValidRepositorySlug((string)$slug);\n}","tryCatchPattern":"try {\n  PhabricatorRepository::assertValidRepositorySlug($slug);\n} catch (Exception $ex) {\n  // collapse separator runs and revalidate, or reject\n}","preventionTips":["Replace invalid-character RUNS ('/[^a-zA-Z0-9._-]+/') with a single hyphen, not per-character.","Reject '..' explicitly in upstream name sources; it doubles as a path-traversal guard."],"tags":["phabricator","php","validation","repository-shortname","path-traversal"],"backgroundTag":"consecutive-separator-characters","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}