{"record":{"id":"ad5b332c05215942","repo":"docker/cli","slug":"duration-cannot-be-negative","errorCode":null,"errorMessage":"duration cannot be negative","messagePattern":"duration cannot be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/duration.go","lineNumber":22,"sourceCode":"\t\"errors\"\n\t\"time\"\n)\n\n// PositiveDurationOpt is an option type for time.Duration that uses a pointer.\n// It behave similarly to DurationOpt but only allows positive duration values.\ntype PositiveDurationOpt struct {\n\tDurationOpt\n}\n\n// Set a new value on the option. Setting a negative duration value will cause\n// an error to be returned.\nfunc (d *PositiveDurationOpt) Set(s string) error {\n\terr := d.DurationOpt.Set(s)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif *d.DurationOpt.value < 0 {\n\t\treturn errors.New(\"duration cannot be negative\")\n\t}\n\treturn nil\n}\n\n// DurationOpt is an option type for time.Duration that uses a pointer. This\n// allows us to get nil values outside, instead of defaulting to 0\ntype DurationOpt struct {\n\tvalue *time.Duration\n}\n\n// NewDurationOpt creates a DurationOpt with the specified duration\nfunc NewDurationOpt(value *time.Duration) *DurationOpt {\n\treturn &DurationOpt{\n\t\tvalue: value,\n\t}\n}\n\n// Set a new value on the option","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/duration.go#L4-L40","documentation":"Returned by PositiveDurationOpt.Set (opts/duration.go:22) after successfully parsing a Go duration string whose value is negative. PositiveDurationOpt wraps DurationOpt but adds the constraint that only non-negative durations are accepted. The underlying parse (time.ParseDuration) succeeds, then the sign check fails.","triggerScenarios":"A CLI flag backed by PositiveDurationOpt receives a negative duration string, e.g., '--stop-timeout=-5' or '--timeout=-1s'. The string parses as a valid Go duration but the numeric value is less than zero.","commonSituations":"Typo with a minus sign in a timeout/stop-timeout flag, a computed duration value that unexpectedly becomes negative and is formatted into the flag, or confusion about whether a flag accepts negative values.","solutions":["Remove the negative sign from the duration value.","If a zero duration is acceptable, use '0s' or '0' instead of a negative value.","Validate computed duration values before formatting them into a CLI flag string."],"exampleFix":"// before: negative duration\n// docker run --stop-timeout=-5 nginx\n\n// after: positive or zero\n// docker run --stop-timeout=5 nginx","handlingStrategy":"validation","validationCode":"func validatePositiveDuration(s string) error {\n    d, err := time.ParseDuration(s)\n    if err != nil {\n        return err\n    }\n    if d < 0 {\n        return fmt.Errorf(\"duration %s must not be negative\", s)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := durationOpt.Set(value); err != nil {\n    if err.Error() == \"duration cannot be negative\" {\n        return fmt.Errorf(\"timeout value %q must be >= 0\", value)\n    }\n    return err\n}","preventionTips":["Validate duration strings are non-negative before setting them on PositiveDurationOpt flags.","Use time.ParseDuration and check the sign before formatting computed durations into flag values.","Default to 0 (which is valid) rather than negative sentinels."],"tags":["duration","validation","cli-flag","timeout"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}