phacility/phabricator · error · PhutilArgumentUsageException

Unable to lock repository "%s": only hosted repositories may

Error message

Unable to lock repository "%s": only hosted repositories may be locked.

What it means

Thrown by `bin/repository lock` during its pre-flight loop when a target repository has `isHosted()` false — i.e. it is an observed/remote repository that Phabricator mirrors in read-only fashion rather than hosting itself. Locking exists to block cluster writes, so it is only meaningful for hosted repositories; the workflow aborts before acquiring any locks.

Source

Thrown at src/applications/repository/management/PhabricatorRepositoryManagementLockWorkflow.php:35

            'wildcard' => true,
          ),
        ));
  }

  public function execute(PhutilArgumentParser $args) {
    $viewer = $this->getViewer();

    $repositories = $this->loadRepositories($args, 'repositories');
    if (!$repositories) {
      throw new PhutilArgumentUsageException(
        pht('Specify one or more repositories to lock.'));
    }

    foreach ($repositories as $repository) {
      $display_name = $repository->getDisplayName();

      if (!$repository->isHosted()) {
        throw new PhutilArgumentUsageException(
          pht(
            'Unable to lock repository "%s": only hosted repositories may be '.
            'locked.',
            $display_name));
      }

      if (!$repository->supportsSynchronization()) {
        throw new PhutilArgumentUsageException(
          pht(
            'Unable to lock repository "%s": only repositories that support '.
            'clustering may be locked.',
            $display_name));
      }

      if (!$repository->getAlmanacServicePHID()) {
        throw new PhutilArgumentUsageException(
          pht(
            'Unable to lock repository "%s": only clustered repositories '.

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Target only hosted repositories: check Repositories → Edit Hosting and pick ones where Phabricator hosts the working copy.
  2. Convert the repository to hosted (Repository → Edit → Hosting → Host, configure serving) if it should be lockable.
  3. If you meant a read-only mirror, skip locking — there are no cluster writes to block.
  4. Filter your target list in advance: host a script that checks `isHosted()` (or the hosting setting in the UI) before invoking lock.

Example fix

// before
$ ./bin/repository lock R2   # R2 is an observed mirror
[1167] Unable to lock repository "rR2": only hosted repositories may be locked.

// after
$ ./bin/repository lock R1   # R1 is hosted
// or: Repository R2 -> Edit Hosting -> "Host a repository" first
Defensive patterns

Strategy: validation

Validate before calling

# Only lock repos that Phabricator hosts (checked via Conduit or the UI);
# shell-level: maintain an explicit allowlist of hosted callsigns.
for r in R1 R2; do grep -qx "$r" hosted-repos.txt || { echo "skip $r (not hosted)"; continue; }; ./bin/repository lock "$r"; done

Type guard

function is_lockable(PhabricatorRepository $repository): bool {
  return $repository->isHosted()
    && $repository->supportsSynchronization()
    && (bool)$repository->getAlmanacServicePHID(); // covers [1167]-[1169] in one check
}

Prevention

When it happens

Trigger: Running `./bin/repository lock R2` where R2 is configured as "Observe a remote repository" or "Import an existing repository" (not hosted); locking a list that mixes hosted and observed repos — the first observed one aborts the whole run.

Common situations: Installations that primarily mirror upstream repos point the lock command at a mirror; after flipping a repo from hosted to observed, old lock scripts keep targeting it.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/e088912496eda680. Report an issue: GitHub.