{"record":{"id":"11704dbbb63b9f5b","repo":"wagoodman/dive","slug":"highestuserwastedpercent-config-value-is-outside-a","errorCode":null,"errorMessage":"highestUserWastedPercent config value is outside allowed range (0-1), given '%f'","messagePattern":"highestUserWastedPercent config value is outside allowed range \\(0-1\\), given '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/dive/cli/internal/command/ci/rules.go","lineNumber":171,"sourceCode":"\t\t\tanalysis.WastedBytes, r.threshold)\n\t}\n\treturn RulePassed, \"\"\n}\n\n// NewHighestUserWastedPercentRule creates a new rule to check percentage of wasted bytes\nfunc NewHighestUserWastedPercentRule(configValue string) (Rule, error) {\n\tif isRuleDisabled(configValue) {\n\t\treturn DisabledRule(ciKeyHighestUserWastedPercent), nil\n\t}\n\n\tthreshold, err := strconv.ParseFloat(configValue, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid highestUserWastedPercent config value, given %q: %v\",\n\t\t\tconfigValue, err)\n\t}\n\n\tif threshold < 0 || threshold > 1 {\n\t\treturn nil, fmt.Errorf(\"highestUserWastedPercent config value is outside allowed range (0-1), given '%f'\",\n\t\t\tthreshold)\n\t}\n\n\treturn &HighestUserWastedPercentRule{\n\t\tBaseRule: BaseRule{\n\t\t\tkey:         ciKeyHighestUserWastedPercent,\n\t\t\tconfigValue: configValue,\n\t\t},\n\t\tthreshold: threshold,\n\t}, nil\n}\n\nfunc (r *HighestUserWastedPercentRule) Evaluate(analysis *image.Analysis) (RuleStatus, string) {\n\tif analysis.WastedUserPercent > r.threshold {\n\t\treturn RuleFailed, fmt.Sprintf(\n\t\t\t\"too many bytes wasted, relative to the user bytes added (%%-user-wasted-bytes=%2.2f > threshold=%v)\",\n\t\t\tanalysis.WastedUserPercent, r.threshold)\n\t}","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/wagoodman/dive/blob/d6c691947f8fda635c952a17ee3b7555379d58f0/cmd/dive/cli/internal/command/ci/rules.go#L153-L189","documentation":"Returned when highestUserWastedPercent parses as a float but is outside [0, 1]. The metric is a fraction of user-layer bytes wasted; 0.1 means 10%. Values above 1 (like 10 for '10%') or negative values are rejected during rule construction.","triggerScenarios":"highestUserWastedPercent: \"0.1\" passes; \"10\" (percent-style), \"1.2\", or \"-1\" fail the range check right after ParseFloat succeeds.","commonSituations":"The classic percent-vs-fraction mistake: copying a policy that says 'fail above 20% wasted' and writing 20 instead of 0.2; incrementing thresholds without renormalizing to fractions.","solutions":["Convert percent to a fraction: 20% -> \"0.2\"","Audit all three CI thresholds for consistent fraction notation","If you meant to make the rule never fail, use the disabled sentinel rather than an out-of-range number","Add a config sanity check to CI that rejects values > 1 in fraction fields"],"exampleFix":"# before\nrules:\n  highestUserWastedPercent: \"20\"\n\n# after\nrules:\n  highestUserWastedPercent: \"0.2\"","handlingStrategy":"validation","validationCode":"f, err := strconv.ParseFloat(cfg.HighestUserWastedPercent, 64)\nif err == nil && (f < 0 || f > 1) {\n    return fmt.Errorf(\"highestUserWastedPercent %f outside [0,1]; use a fraction like 0.2\", f)\n}","typeGuard":"func isValidFraction(s string) bool {\n    f, err := strconv.ParseFloat(s, 64)\n    return err == nil && f >= 0 && f <= 1\n}","tryCatchPattern":"rule, err := ci.NewHighestUserWastedPercentRule(value)\nif err != nil && strings.Contains(err.Error(), \"outside allowed range\") {\n    // suggest converting percent to fraction in user-facing output\n}\nif err != nil { return err }","preventionTips":["Keep all ratio thresholds in [0,1] fraction form","Add unit tests that reject >1 values in CI config parsers","When a policy says N%, write N/100 in the config"],"tags":["ci","config","validation","range","rules"],"backgroundTag":null,"analyzedSha":"d6c691947f8fda635c952a17ee3b7555379d58f0","analyzedAt":"2026-08-15T09:42:35.293Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}