{"record":{"id":"6363efb9f4eb02a7","repo":"nextcloud/all-in-one","slug":"location-and-remote-repo-url-are-mutually-exclusiv","errorCode":null,"errorMessage":"Location and remote repo url are mutually exclusive!","messagePattern":"Location and remote repo url are mutually exclusive!","errorType":"validation","errorClass":"InvalidSettingConfigurationException","httpStatus":422,"severity":"error","filePath":"php/src/Data/ConfigurationManager.php","lineNumber":731,"sourceCode":"        return 'dc=' . implode(',dc=', explode('.', $domain));\n    }\n\n    /**\n     * @throws InvalidSettingConfigurationException\n     */\n    public function setBorgLocationVars(string $location, string $repo) : void {\n        $this->validateBorgLocationVars($location, $repo);\n        $this->startTransaction();\n        $this->borgBackupHostLocation = $location;\n        $this->borgRemoteRepo = $repo;\n        $this->commitTransaction();\n    }\n\n    private function validateBorgLocationVars(string $location, string $repo) : void {\n        if ($location === '' && $repo === '') {\n            throw new InvalidSettingConfigurationException(\"Please enter a path or a remote repo url!\");\n        } elseif ($location !== '' && $repo !== '') {\n            throw new InvalidSettingConfigurationException(\"Location and remote repo url are mutually exclusive!\");\n        }\n\n        if ($location !== '') {\n            $isValidPath = false;\n            if (str_starts_with($location, '/') && !str_ends_with($location, '/')) {\n                $isValidPath = true;\n            } elseif ($location === 'nextcloud_aio_backupdir') {\n                $isValidPath = true;\n            }\n\n            if (!$isValidPath) {\n                throw new InvalidSettingConfigurationException(\"The path must start with '/', and must not end with '/'! Another option is to use the docker volume name 'nextcloud_aio_backupdir'.\");\n            }\n\n            // Prevent backup to be contained in Nextcloud Datadir as this will delete the backup archive upon restore\n            // See https://github.com/nextcloud/all-in-one/issues/6607\n            if (str_starts_with($location . '/', rtrim($this->nextcloudDatadirMount, '/') . '/')) {\n                throw new InvalidSettingConfigurationException(\"The path must not be a children of or equal to NEXTCLOUD_DATADIR, which is currently set to \" . $this->nextcloudDatadirMount);","sourceCodeStart":713,"sourceCodeEnd":749,"githubUrl":"https://github.com/nextcloud/all-in-one/blob/6b788eec5e61733cf03ed380a3572e43ae3f11ce/php/src/Data/ConfigurationManager.php#L713-L749","documentation":"validateBorgLocationVars() in ConfigurationManager rejects requests where both a local backup path and a borg remote repository URL are provided — they are mutually exclusive because borg either writes to a mounted path or to a remote repository, never both. Throws InvalidSettingConfigurationException → HTTP 422 in the AIO UI. Reached from the backup settings form (setBorgLocationVars) and the restore form.","triggerScenarios":"POST with borg_backup_host_location='/mnt/backup' and borg_remote_repo='ssh://user@host/./repo' at the same time; switching from local to remote backup by filling the new field but leaving the old value in place.","commonSituations":"Users migrating from local backups to a remote repository; forms that keep both inputs filled from previous state.","solutions":["Decide on one target and clear the other field before submitting","For local backups keep only the path; for remote keep only the repo URL","When switching permanently, submit the new value with the other field left empty — setBorgLocationVars stores both, emptying the unused one"],"exampleFix":"// before\nborg_backup_host_location = '/mnt/backup'\nborg_remote_repo = 'ssh://user@host/./repo'\n// after\nborg_backup_host_location = ''\nborg_remote_repo = 'ssh://user@host/./repo'","handlingStrategy":"validation","validationCode":"if (trim($location) !== '' && trim($repo) !== '') {\n    $errors[] = 'Choose either a local path or a remote repo url, not both';\n}","typeGuard":null,"tryCatchPattern":"use AIO\\Data\\InvalidSettingConfigurationException;\n\ntry {\n    $configurationManager->setBorgLocationVars($location, $repo);\n} catch (InvalidSettingConfigurationException $e) {\n    $formErrors[] = $e->getMessage();\n}","preventionTips":["Model the two inputs as a radio choice (local vs remote) in the form so both can never be set","When switching backup targets, clear the other field in the same submit","Keep the mutual-exclusion rule in any scripts that post the config endpoint"],"tags":["php","nextcloud-aio","borg-backup","configuration","input-validation"],"backgroundTag":"mutually-exclusive-fields","analyzedSha":"6b788eec5e61733cf03ed380a3572e43ae3f11ce","analyzedAt":"2026-08-21T05:47:24.382Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}