{"record":{"id":"f20c8b03b784f3ba","repo":"tsenart/vegeta","slug":"rate-format-q-doesn-t-match-the-freq-duration","errorCode":null,"errorMessage":"-rate format %q doesn't match the \"freq/duration\" format (i.e. 50/1s)","messagePattern":"-rate format %q doesn't match the \"freq/duration\" format \\(i\\.e\\. 50/1s\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"flags.go","lineNumber":79,"sourceCode":"\t*l = strings.Split(v, \",\")\n\treturn nil\n}\n\nfunc (l csl) String() string { return strings.Join(l, \",\") }\n\ntype rateFlag struct{ *vegeta.Rate }\n\nfunc (f *rateFlag) Set(v string) (err error) {\n\tif v == \"infinity\" {\n\t\treturn nil\n\t}\n\n\tps := strings.SplitN(v, \"/\", 2)\n\tswitch len(ps) {\n\tcase 1:\n\t\tps = append(ps, \"1s\")\n\tcase 0:\n\t\treturn fmt.Errorf(\"-rate format %q doesn't match the \\\"freq/duration\\\" format (i.e. 50/1s)\", v)\n\t}\n\n\tf.Freq, err = strconv.Atoi(ps[0])\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif f.Freq == 0 {\n\t\treturn nil\n\t}\n\n\tswitch ps[1] {\n\tcase \"ns\", \"us\", \"µs\", \"ms\", \"s\", \"m\", \"h\":\n\t\tps[1] = \"1\" + ps[1]\n\t}\n\n\tf.Per, err = time.ParseDuration(ps[1])\n\treturn err","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/tsenart/vegeta/blob/cf5811269046c672a604b1eb352204d30f16ae4a/flags.go#L61-L97","documentation":"vegeta's Rate flag parses '-rate' as freq/duration. strings.SplitN(v,\"/\",2) yielding 0 parts (an empty -rate value) means the value cannot match the documented \"freq/duration\" format, so Set rejects it with this message.","triggerScenarios":"Passing an empty string to the -rate flag (e.g. -rate=\"\" or an unbound shell variable expanding to nothing), so the split produces zero parts.","commonSituations":"Scripted invocations where a RATE variable is unset/empty; config templating leaving the flag blank; copy-pasted examples that omit the value.","solutions":["Supply a value in \"freq/duration\" form, e.g. -rate=50/1s.","Use the shorthand -rate=50, which defaults the duration to 1s.","In scripts, guard against empty variables: ${RATE:-50/1s}.","Note Atoi errors on the freq part produce a different error; this one is specifically for an empty value."],"exampleFix":"// before\nvegeta attack -rate=$RATE ...   # RATE unset -> empty\n// after\nvegeta attack -rate=50/1s ...","handlingStrategy":"validation","validationCode":"func validRate(s string) bool {\n\tif s == \"\" {\n\t\treturn false\n\t}\n\tparts := strings.SplitN(s, \"/\", 2)\n\tif _, err := strconv.Atoi(parts[0]); err != nil {\n\t\treturn false\n\t}\n\tif len(parts) == 2 {\n\t\tif _, err := time.ParseDuration(parts[1]); err != nil {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass an empty -rate value; default it in scripts (${RATE:-50/1s}).","Use the documented 'freq/duration' form like 50/1s.","Remember bare integers like 50 are valid (duration defaults to 1s).","Fail fast in wrappers if the rate variable is unset."],"tags":["cli","flag-parsing","rate-limit"],"backgroundTag":"cli-flag-parse-error","analyzedSha":"cf5811269046c672a604b1eb352204d30f16ae4a","analyzedAt":"2026-08-31T11:04:20.464Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}