{"record":{"id":"31647a5a53f246f5","repo":"etcd-io/etcd","slug":"specify-either-addr-or-download-ver","errorCode":null,"errorMessage":"specify either 'addr' or 'download-ver'","messagePattern":"specify either 'addr' or 'download-ver'","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/etcd-dump-metrics/main.go","lineNumber":50,"sourceCode":"\nvar lg *zap.Logger\n\nfunc init() {\n\tvar err error\n\tlg, err = logutil.CreateDefaultZapLogger(zap.InfoLevel)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\nfunc main() {\n\taddr := flag.String(\"addr\", \"\", \"etcd metrics URL to fetch from (empty to use current git branch)\")\n\tdownloadVer := flag.String(\"download-ver\", \"\", \"etcd binary version to download and fetch metrics from\")\n\tdebug := flag.Bool(\"debug\", false, \"true to enable debug logging\")\n\tflag.Parse()\n\n\tif *addr != \"\" && *downloadVer != \"\" {\n\t\tpanic(\"specify either 'addr' or 'download-ver'\")\n\t}\n\tif *debug {\n\t\tvar err error\n\t\tlg, err = logutil.CreateDefaultZapLogger(zap.DebugLevel)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\tep := *addr\n\tif ep == \"\" {\n\t\tif *downloadVer != \"\" {\n\t\t\tver := *downloadVer\n\n\t\t\t// download release binary to temporary directory\n\t\t\td, err := os.MkdirTemp(os.TempDir(), ver)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/etcd-io/etcd/blob/f744d457f484e9f748a0700b48ef96dcf792df33/tools/etcd-dump-metrics/main.go#L32-L68","documentation":"etcd-dump-metrics' main() accepts two mutually exclusive sources for metrics: -addr (an already-running etcd's metrics URL) and -download-ver (download an etcd binary of that version and scrape it locally). If both flags are non-empty at once, main panics with 'specify either addr or download-ver' because the two modes would conflict over which endpoint to fetch.","triggerScenarios":"Running etcd-dump-metrics with both flags set on the command line, e.g. `etcd-dump-metrics -addr http://localhost:2379/metrics -download-ver v3.5.0`. Either flag alone (or neither, which defaults to building from the current git branch) is fine; only the both-set combination panics.","commonSituations":"Copy-pasted invocations in scripts where one mode was switched to another without removing the old flag; CI pipelines that template both flags unconditionally; assuming download-ver is ignored when addr is given.","solutions":["Remove one of the two flags: keep `-addr` to scrape a live endpoint, or keep `-download-ver` to spin up a downloaded binary.","If scripting, derive the invocation from a single mode variable so the two flags can never both be emitted.","If neither flag is passed, confirm the fallback (build from current git branch) is what you want; otherwise pass exactly one."],"exampleFix":"# before\netcd-dump-metrics -addr http://localhost:2379/metrics -download-ver v3.5.0\n# panic: specify either 'addr' or 'download-ver'\n\n# after (scrape a live endpoint)\netcd-dump-metrics -addr http://localhost:2379/metrics\n# after (download and run a specific version)\netcd-dump-metrics -download-ver v3.5.0","handlingStrategy":"validation","validationCode":"# Validate in your wrapper before calling the tool:\nif [ -n \"$ADDR\" ] && [ -n \"$DOWNLOAD_VER\" ]; then\n\techo \"pass either -addr or -download-ver, not both\" >&2; exit 2\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass exactly one of -addr / -download-ver per invocation.","In scripts, model the mode as a single variable that expands to one flag.","Audit copy-pasted CI commands when switching between live-scrape and download modes."],"tags":["etcd-dump-metrics","cli","usage","panic"],"backgroundTag":null,"analyzedSha":"f744d457f484e9f748a0700b48ef96dcf792df33","analyzedAt":"2026-08-15T09:39:50.079Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}