{"record":{"id":"0a4d9e8c77f03504","repo":"hashicorp/nomad","slug":"error-parsing-gittimeout-w","errorCode":null,"errorMessage":"error parsing GitTimeout: %w","messagePattern":"error parsing GitTimeout: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/config/artifact.go","lineNumber":55,"sourceCode":"func ArtifactConfigFromAgent(c *config.ArtifactConfig) (*ArtifactConfig, error) {\n\thttpReadTimeout, err := time.ParseDuration(*c.HTTPReadTimeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing HTTPReadTimeout: %w\", err)\n\t}\n\n\thttpMaxSize, err := humanize.ParseBytes(*c.HTTPMaxSize)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing HTTPMaxSize: %w\", err)\n\t}\n\n\tgcsTimeout, err := time.ParseDuration(*c.GCSTimeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing GCSTimeout: %w\", err)\n\t}\n\n\tgitTimeout, err := time.ParseDuration(*c.GitTimeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing GitTimeout: %w\", err)\n\t}\n\n\thgTimeout, err := time.ParseDuration(*c.HgTimeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing HgTimeout: %w\", err)\n\t}\n\n\ts3Timeout, err := time.ParseDuration(*c.S3Timeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing S3Timeout: %w\", err)\n\t}\n\n\tdecompressionSizeLimit, err := humanize.ParseBytes(*c.DecompressionSizeLimit)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing DecompressionLimitSize: %w\", err)\n\t}\n\n\treturn &ArtifactConfig{","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/config/artifact.go#L37-L73","documentation":"ArtifactConfigFromAgent parses GitTimeout with time.ParseDuration to build the internal ArtifactConfig used for git artifact fetches. An unparseable duration string produces this wrapped error and nil config.","triggerScenarios":"Calling ArtifactConfigFromAgent when GitTimeout is a string time.ParseDuration rejects: \"300\" (no unit), \"5mins\", \"5 min\", empty string, or negative-malformed values like \"-5m-\".","commonSituations":"git_timeout in the Nomad client artifact config missing its unit; config generated from scripts/env vars yielding empty or malformed strings; copy-paste of values like \"30m s\" with stray characters.","solutions":["Set git_timeout to a valid Go duration, e.g. \"30m\" or \"1h\", in the agent config","Inspect the rendered config file (nomad agent -config output / logs) to confirm the actual string passed in","Validate with time.ParseDuration at config-load time in tooling that generates Nomad configs"],"exampleFix":"// before\ngit_timeout = \"900\"\n// after\ngit_timeout = \"900s\"","handlingStrategy":"validation","validationCode":"if _, err := time.ParseDuration(*c.GitTimeout); err != nil {\n    return fmt.Errorf(\"invalid git_timeout %q: %w\", *c.GitTimeout, err)\n}","typeGuard":"func validDuration(s *string) bool { if s == nil { return false }; _, err := time.ParseDuration(*s); return err == nil }","tryCatchPattern":"cfg, err := config.ArtifactConfigFromAgent(agentCfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"error parsing GitTimeout\") {\n        return fmt.Errorf(\"git_timeout must be a Go duration like 30m: %w\", err)\n    }\n    return err\n}","preventionTips":["Use standard Go duration syntax (h/m/s/ms) in git_timeout","Lint generated Nomad configs before applying them","Default timeout values explicitly rather than relying on empty strings"],"tags":["config","parsing","duration","go"],"backgroundTag":"invalid-duration-or-size-config","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}