{"record":{"id":"05d86a2c97729d7d","repo":"matryer/xbar","slug":"bad-interval-unit-s","errorCode":null,"errorMessage":"bad interval unit: %s","messagePattern":"bad interval unit: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/plugins/refresh_interval.go","lineNumber":108,"sourceCode":"\t}\n\tnewVarFilename := newFilename + variableJSONFileExt\n\tnewVarFullPath := filepath.Join(pluginDirectory, newVarFilename)\n\tif err := os.Rename(oldVarFullPath, newVarFullPath); err != nil {\n\t\treturn \"\", RefreshInterval{}, errors.Wrap(err, \"rename plugin vars file to new refresh interval\")\n\t}\n\treturn newFilename, refreshInterval, nil\n}\n\nfunc validateRefreshInterval(refreshInterval RefreshInterval) error {\n\tif n := refreshInterval.N; n < 1 {\n\t\treturn errors.Errorf(\"bad interval value: %d\", n)\n\t}\n\tfor _, unit := range []string{\"days\", \"hours\", \"minutes\", \"seconds\", \"milliseconds\"} {\n\t\tif refreshInterval.Unit == unit {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn errors.Errorf(\"bad interval unit: %s\", refreshInterval.Unit)\n}\n\n// ParseFilenameInterval parses the filename to extract the refresh interval\n// or returns a default if it is do so.\nfunc ParseFilenameInterval(filename string) (RefreshInterval, error) {\n\t// ignore disabled piece\n\tfilename = strings.TrimSuffix(filename, disabledPluginExtension)\n\tintervalStr := findIntervalInFilename(filename)\n\tif intervalStr == \"\" {\n\t\treturn defaultRefreshInterval, nil\n\t}\n\tinterval, err := parseInterval(intervalStr)\n\tif err != nil {\n\t\treturn defaultRefreshInterval, errors.Errorf(\"%s (from %s)\", err.Error(), filename)\n\t}\n\treturn interval, nil\n}\n","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/plugins/refresh_interval.go#L90-L126","documentation":"validateRefreshInterval checks Unit against the fixed list days, hours, minutes, seconds, milliseconds and returns errors.Errorf(\"bad interval unit: %s\") for anything else. SetRefreshInterval wraps it as 'invalid refresh interval'. The library only supports these five units because they map to xbar filename interval suffixes (d/h/m/s/ms).","triggerScenarios":"Calling plugins.SetRefreshInterval with RefreshInterval{Unit: \"week\"}, \"Minutes\", \"\", or any casing/typo outside the exact five lowercase unit strings.","commonSituations":"Hand-written config using \"weeks\" or \"days\" with wrong casing; JSON deserialization of a user-supplied unit; translating a Go time.Duration string (\"5m0s\") into Unit; a UI locale differences.","solutions":["Use exactly one of \"days\", \"hours\", \"minutes\", \"seconds\", \"milliseconds\" for Unit","Normalize/sanitize user input (lowercase, map synonyms like \"week\" -> {N:7, Unit:\"days\"}) before constructing RefreshInterval","Pre-construct intervals only from known constants rather than raw strings"],"exampleFix":"// before\n_, _, err := plugins.SetRefreshInterval(dir, path, plugins.RefreshInterval{N: 1, Unit: \"Week\"})\n// after\nunit := strings.ToLower(unitInput)\nif unit == \"week\" {\n    unit = \"days\"\n    n *= 7\n}\n_, _, err = plugins.SetRefreshInterval(dir, path, plugins.RefreshInterval{N: n, Unit: unit})","handlingStrategy":"validation","validationCode":"var validUnits = map[string]bool{\n    \"days\": true, \"hours\": true, \"minutes\": true,\n    \"seconds\": true, \"milliseconds\": true,\n}\nfunc validUnit(u string) bool { return validUnits[strings.ToLower(u)] }","typeGuard":null,"tryCatchPattern":"if !validUnit(iv.Unit) {\n    return fmt.Errorf(\"unit %q not supported; use days|hours|minutes|seconds|milliseconds\", iv.Unit)\n}\n_, _, err := plugins.SetRefreshInterval(dir, path, iv)","preventionTips":["Only build RefreshInterval from the five exact lowercase unit strings","Normalize user input with strings.ToLower and map synonyms (week->7 days, min->minutes)","Never derive Unit from time.Duration.String() output"],"tags":["go","validation","refresh-interval","input"],"backgroundTag":"invalid-argument-value","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}