{"record":{"id":"3ff04c54893d9766","repo":"jdx/mise","slug":"choose-github-relay-repo-owner-repo-or-github","errorCode":null,"errorMessage":"choose --github-relay-repo OWNER/REPO or --github-relay-all-repos, not both","messagePattern":"choose --github-relay-repo OWNER/REPO or --github-relay-all-repos, not both","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/github_relay.rs","lineNumber":29,"sourceCode":"    repositories: std::collections::BTreeSet<String>,\n    #[cfg(any(unix, test))]\n    all: bool,\n}\n\nimpl Scope {\n    pub(crate) fn from_flags(\n        enabled: bool,\n        repositories: &[String],\n        all: bool,\n    ) -> Result<Option<Self>> {\n        if !enabled {\n            if all || !repositories.is_empty() {\n                bail!(\"repository scope requires --github-relay-read-only\");\n            }\n            return Ok(None);\n        }\n        if all != repositories.is_empty() {\n            bail!(\"choose --github-relay-repo OWNER/REPO or --github-relay-all-repos, not both\");\n        }\n        let repositories: std::collections::BTreeSet<String> = repositories\n            .iter()\n            .map(|repo| repository(repo))\n            .collect::<Result<_>>()?;\n        #[cfg(not(any(unix, test)))]\n        let _ = repositories;\n        Ok(Some(Self {\n            #[cfg(unix)]\n            options: Options::default(),\n            #[cfg(any(unix, test))]\n            repositories,\n            #[cfg(any(unix, test))]\n            all,\n        }))\n    }\n\n    #[cfg(any(unix, test))]","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/github_relay.rs#L11-L47","documentation":"from_flags rejects mutually exclusive repository scoping: --github-relay-all-repos (all=true) and explicit --github-relay-repo entries are contradictory. The guard `all != repositories.is_empty()` fires when exactly one side is set incorrectly — specifically when both are given (all=true AND repos present), or when neither is given while relay is enabled is allowed implicitly? No: it fires when all=true together with a non-empty repositories list (both selected), since enabling relay with neither falls through to all=false/empty which means no scope restriction.","triggerScenarios":"Calling from_flags(enabled=true, repositories=[...], all=true) — both --github-relay-all-repos and one or more --github-relay-repo flags present on the command line.","commonSituations":"Building a command incrementally and leaving an old --github-relay-repo flag in place after switching to --github-relay-all-repos; a generated or templated command emitting both options.","solutions":["Keep only --github-relay-all-repos to relay every repository","Or keep only the --github-relay-repo OWNER/REPO flags for an explicit allowlist","Review the full command line/scripts for duplicated relay scope options"],"exampleFix":"// before\nmycli --github-relay-read-only --github-relay-all-repos --github-relay-repo org/repo\n// after (pick one)\nmycli --github-relay-read-only --github-relay-all-repos\n// or\nmycli --github-relay-read-only --github-relay-repo org/repo","handlingStrategy":"validation","validationCode":"// Exactly one scoping mode must be chosen\nlet has_repos = args.iter().any(|a| a.starts_with(\"--github-relay-repo\"));\nlet has_all = args.iter().any(|a| a == \"--github-relay-all-repos\");\nif has_repos && has_all { panic!(\"choose one relay scope mode, not both\"); }","typeGuard":null,"tryCatchPattern":"match err {\n    RelayConfigError::ConflictingScope => eprintln!(\"use --github-relay-all-repos OR --github-relay-repo, not both\"),\n    e => return Err(e),\n}","preventionTips":["Decide on one scoping mode before building the command line","When editing generated commands, remove the old scope flag entirely","Encode the choice in a single config key rather than multiple flags"],"tags":["cli","github-relay","flags","conflicting-options"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}