{"record":{"id":"c651dd8b3b376a61","repo":"matryer/xbar","slug":"s-from-s","errorCode":null,"errorMessage":"%s (from %s)","messagePattern":"(.+?) \\(from (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/plugins/refresh_interval.go","lineNumber":122,"sourceCode":"\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\nfunc findIntervalInFilename(filename string) string {\n\tif filename == \"\" {\n\t\treturn \"\"\n\t}\n\tif !IsPluginEnabled(filename) {\n\t\tfilename = strings.TrimSuffix(filename, disabledPluginExtension)\n\t}\n\tfn := filename\n\text := filepath.Ext(filename)\n\tif ext != \"\" {\n\t\tfn = fn[:len(fn)-len(ext)]\n\t}\n\tsegs := strings.Split(fn, \".\")\n\tif len(segs) == 1 {","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/plugins/refresh_interval.go#L104-L140","documentation":"ParseFilenameInterval extracts the interval token from a plugin filename (the dotted segment before the extension) and parses it. If parseInterval fails, the library returns the default interval along with errors.Errorf(\"%s (from %s)\") embedding the inner error and the full filename, so the developer can see which file had the malformed interval.","triggerScenarios":"Calling plugins.ParseFilenameInterval (directly or via GetInstalledPluginMetadata/NewPlugin) on a filename whose last dotted segment is not a valid interval token, e.g. \"weather.5x.py\" or \"notes..py\" producing an empty/suffix parse failure; note filenames with NO interval segment return the default without error.","commonSituations":"Hand-renamed plugin files (\"weather.5m.py\" edited to \"weather.5min.py\"); plugin filenames where the final segment collides with interval parsing, like \"my.tool.py\" (parses unit 'l' -> bad unit); downloading a plugin renamed by a browser.","solutions":["Rename the plugin file so its final dotted segment is a valid interval token: <name>.<N><d|h|m|s|ms>.<ext>, e.g. weather.5m.py","If the plugin should just use the default interval, remove the dotted segment entirely (weather.py) — empty interval yields the default with no error","Handle the returned defaultRefreshInterval when this error occurs, since the interval value is still usable (default 1 minute)"],"exampleFix":"// before\niv, err := plugins.ParseFilenameInterval(\"weather.5min.py\") // bad interval value: 5mi...\n// after\n// rename file to a valid token first: weather.5m.py\niv, err := plugins.ParseFilenameInterval(\"weather.5m.py\") // -> {5, minutes}\nif err != nil {\n    iv = plugins.RefreshInterval{N: 1, Unit: \"minutes\"} // accept default\n}","handlingStrategy":"fallback","validationCode":"var intervalRe = regexp.MustCompile(`\\.\\d+(ms|[dhms])\\.[^.]+$`)\nfunc filenameHasValidInterval(name string) bool {\n    return intervalRe.MatchString(strings.TrimSuffix(name, \".stp\"))\n}","typeGuard":null,"tryCatchPattern":"iv, err := plugins.ParseFilenameInterval(filename)\nif err != nil {\n    log.Printf(\"using default interval: %v\", err)\n    iv = plugins.RefreshInterval{N: 1, Unit: \"minutes\"} // default already returned; safe to ignore\n}","preventionTips":["Treat the returned default interval as valid even when err != nil","Sanitize plugin filenames at install time to enforce <name>.<N><unit>.<ext>","Avoid dots inside plugin base names (use hyphens instead)"],"tags":["go","parsing","filenames","refresh-interval"],"backgroundTag":"invalid-argument-value","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}