{"record":{"id":"eb947521f92d3250","repo":"cloudflare/cloudflared","slug":"expected-duration-found-t-for-s","errorCode":null,"errorMessage":"expected duration found %T for %s","messagePattern":"expected duration found %T for (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/configuration.go","lineNumber":297,"sourceCode":"func (c *configFileSettings) Int(name string) (int, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif v, ok := raw.(int); ok {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn 0, fmt.Errorf(\"expected int found %T for %s\", raw, name)\n\t}\n\treturn 0, nil\n}\n\nfunc (c *configFileSettings) Duration(name string) (time.Duration, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tswitch v := raw.(type) {\n\t\tcase time.Duration:\n\t\t\treturn v, nil\n\t\tcase string:\n\t\t\treturn time.ParseDuration(v)\n\t\t}\n\t\treturn 0, fmt.Errorf(\"expected duration found %T for %s\", raw, name)\n\t}\n\treturn 0, nil\n}\n\nfunc (c *configFileSettings) Float64(name string) (float64, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif v, ok := raw.(float64); ok {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn 0, fmt.Errorf(\"expected float found %T for %s\", raw, name)\n\t}\n\treturn 0, nil\n}\n\nfunc (c *configFileSettings) String(name string) (string, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif v, ok := raw.(string); ok {\n\t\t\treturn v, nil","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/config/configuration.go#L279-L315","documentation":"Type-mismatch error in configFileSettings.Duration: a config-file setting read as a duration is neither a time.Duration nor a duration string (e.g. it is an int, bool, or map in the parsed YAML). The accessor returns zero and this error instead of guessing a conversion.","triggerScenarios":"Calling Duration(name) where the stored value is an int, bool, or a string in an invalid format is handled separately (ParseDuration error); this error fires for non-duration, non-string types — e.g. `grace-period: 5` (bare number instead of \"5s\").","commonSituations":"Users writing bare numbers in YAML where a duration string like 30s/1m is required; config keys copied from examples with wrong units.","solutions":["Write the value as a duration string with a unit in the config file (grace-period: 30s).","If a bare number is intentional seconds, change the call site to read Int and multiply by time.Second.","Handle the ParseDuration error path separately for string values with bad formats."],"exampleFix":"// before (config.yml)\ngrace-period: 30\n// after\ngrace-period: 30s","handlingStrategy":"validation","validationCode":"// Go\ntypeAssertDuration := func(v interface{}) (time.Duration, error) {\n    switch t := v.(type) {\n    case time.Duration: return t, nil\n    case string: return time.ParseDuration(t)\n    default: return 0, fmt.Errorf(\"not a duration: %T\", v)\n    }\n}","typeGuard":"func asDuration(v interface{}) (time.Duration, bool) { d, ok := v.(time.Duration); return d, ok }","tryCatchPattern":"d, err := settings.Duration(\"grace-period\")\nif err != nil {\n    log.Printf(\"'grace-period' must be like 30s/5m: %v\", err)\n    return err\n}","preventionTips":["Always include a unit suffix for durations in config files","Validate duration strings with time.ParseDuration in CI","Document expected units next to each duration setting"],"tags":["configuration","type-mismatch","duration"],"backgroundTag":"invalid-duration-format","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}