{"record":{"id":"f65b12a53598b2f0","repo":"jdx/mise","slug":"relay-options-require-github-relay-read-only","errorCode":null,"errorMessage":"relay options require --github-relay-read-only","messagePattern":"relay options require --github-relay-read-only","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/github_relay.rs","lineNumber":86,"sourceCode":"            jsonl: false,\n            max_duration: std::time::Duration::ZERO,\n            request_timeout: std::time::Duration::from_secs(300),\n            concurrency: 8,\n        }\n    }\n}\n\n/// Resolve observability and limits only after explicit access authorization.\npub(crate) fn configure(\n    scope: Option<Scope>,\n    log_requests: bool,\n    no_log_requests: bool,\n    format: Option<&str>,\n    max_duration: Option<&str>,\n) -> Result<Option<Scope>> {\n    let Some(scope) = scope else {\n        if log_requests || no_log_requests || format.is_some() || max_duration.is_some() {\n            bail!(\"relay options require --github-relay-read-only\");\n        }\n        return Ok(None);\n    };\n    let settings = crate::config::Settings::get();\n    let settings = &settings.github_relay;\n    let format = format.unwrap_or(&settings.log_format);\n    if !matches!(format, \"text\" | \"jsonl\") {\n        bail!(\"relay log format must be text or jsonl\");\n    }\n    let timeout = duration::parse_duration(&settings.request_timeout)?;\n    if timeout.is_zero() {\n        bail!(\"relay request timeout must be greater than zero\");\n    }\n    if !(1..=32).contains(&settings.concurrency) {\n        bail!(\"relay concurrency must be between 1 and 32\");\n    }\n    let max_duration = duration::parse_duration(max_duration.unwrap_or(&settings.max_duration))?;\n    if std::time::Instant::now().checked_add(timeout).is_none()","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/github_relay.rs#L68-L104","documentation":"GitHubRelay::Scope::configure applies log/observability settings to an existing relay scope. If no relay scope exists (scope=None) but log-related relay flags were passed (--log-requests, --no-log-requests, a log format, or a max duration), it bails: those options only make sense when the relay is enabled via --github-relay-read-only.","triggerScenarios":"Calling configure (via npm_command or cli_observability_overrides) with scope=None and any of log_requests=true, no_log_requests=true, format=Some(_), or max_duration=Some(_).","commonSituations":"Passing --github-relay-log-format or --github-relay-max-duration without first enabling --github-relay-read-only; running an npm subcommand that forwards relay observability flags when the relay was never turned on.","solutions":["Enable the relay first with --github-relay-read-only, then pass the log options","Remove the relay log/format/duration flags when the relay is disabled","Check that the code path creating the Scope ran successfully before configure is called"],"exampleFix":"// before\nmycli --github-relay-log-requests\n// after\nmycli --github-relay-read-only --github-relay-log-requests","handlingStrategy":"validation","validationCode":"// Only pass log flags when the relay scope exists\nlet log_flags = args.iter().filter(|a| a.starts_with(\"--github-relay-log\")).count();\nif log_flags > 0 && !args.contains(&\"--github-relay-read-only\") {\n    panic!(\"relay log options require --github-relay-read-only\");\n}","typeGuard":null,"tryCatchPattern":"match err {\n    RelayConfigError::LogOptionsWithoutScope => eprintln!(\"enable --github-relay-read-only before using relay log options\"),\n    e => return Err(e),\n}","preventionTips":["Enable the relay before configuring its observability options","Gate relay log flags behind the same UI/CLI section as the enable flag","Document that log options are scoped to the read-only relay"],"tags":["cli","github-relay","logging","flags"],"backgroundTag":"missing-required-flag","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"}