{"record":{"id":"8c693c15e2334e72","repo":"phacility/phabricator","slug":"this-repository-is-read-only-over-ssh","errorCode":null,"errorMessage":"This repository is read-only over SSH.","messagePattern":"This repository is read-only over SSH\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/diffusion/ssh/DiffusionSSHWorkflow.php","lineNumber":294,"sourceCode":"    $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH;\n    if ($repository->canServeProtocol($protocol, true)) {\n      $can_push = PhabricatorPolicyFilter::hasCapability(\n        $viewer,\n        $repository,\n        DiffusionPushCapability::CAPABILITY);\n      if (!$can_push) {\n        throw new Exception(\n          pht('You do not have permission to push to this repository.'));\n      }\n    } else {\n      if ($protocol_command !== null) {\n        throw new Exception(\n          pht(\n            'This repository is read-only over SSH (tried to execute '.\n            'protocol command \"%s\").',\n            $protocol_command));\n      } else {\n        throw new Exception(\n          pht('This repository is read-only over SSH.'));\n      }\n    }\n\n    $this->hasWriteAccess = true;\n    return $this->hasWriteAccess;\n  }\n\n  protected function shouldSkipReadSynchronization() {\n    $viewer = $this->getSSHUser();\n\n    // Currently, the only case where devices interact over SSH without\n    // assuming user credentials is when synchronizing before a read. These\n    // synchronizing reads do not themselves need to be synchronized.\n    if ($viewer->isOmnipotent()) {\n      return true;\n    }\n","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php#L276-L312","documentation":"The generic sibling of the protocol-command error: canServeProtocol() says the repository cannot serve writes over SSH and the SSH request carried no recognizable write protocol command. This shape is typical of the svnserve workflow, where writes are detected later inside the protocol stream. Reads over SSH may still work, but all write traffic is refused.","triggerScenarios":"An svn+ssh session against a repository whose SSH URI serving mode is 'Read Only' or 'Off' - SVN mixes reads and writes in one session, so a checkout that attempts a commit hits this mid-session.","commonSituations":"Same misconfiguration as the protocol-command variant: SSH serving mode left read-only after repository setup or a URI migration; SVN users hit it without ever issuing an explicit push command.","solutions":["Set 'Serve Over SSH' to 'Read/Write' on the repository's SSH URI (Manage URIs)","Use HTTP for SVN access if SSH write serving is disabled by policy","Re-check URI serving modes after cluster/device or hosting changes to make sure they survived"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!$repository->canServeProtocol(\n      PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH,\n      true)) {\n  // do not begin a write-capable SVN session\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Because SVN sessions mix reads and writes, gate the whole session on write serving, not just commit commands","Monitor URI serving-mode changes on SVN repositories"],"tags":["phabricator","diffusion","ssh","svn","uri-configuration","read-only"],"backgroundTag":"repository-read-only","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}