{"record":{"id":"761ed6d410949821","repo":"docker/cli","slug":"invalid-restart-policy-format-no-policy-provided","errorCode":null,"errorMessage":"invalid restart policy format: no policy provided before colon","messagePattern":"invalid restart policy format: no policy provided before colon","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/parse.go","lineNumber":89,"sourceCode":"}\n\n// ParseRestartPolicy parses a restart policy string (\"name[:max-retries]\")\n// into a [container.RestartPolicy].\n//\n// Parsing is syntactic only; semantic validation is deferred to the daemon/API.\n// An empty input returns a zero-value policy for backward compatibility. The\n// retry count, if set, must be an integer (negative values are allowed here\n// but may be rejected by the daemon).\nfunc ParseRestartPolicy(policy string) (container.RestartPolicy, error) {\n\tif policy == \"\" {\n\t\t// For backward compatibility, do not set an explicit default (\"no\"),\n\t\t// as older daemons may not support it.\n\t\treturn container.RestartPolicy{}, nil\n\t}\n\n\tname, count, ok := strings.Cut(policy, \":\")\n\tif ok && name == \"\" {\n\t\treturn container.RestartPolicy{}, errors.New(\"invalid restart policy format: no policy provided before colon\")\n\t}\n\n\tvar retryCount int\n\tif count != \"\" {\n\t\tc, err := strconv.Atoi(count)\n\t\tif err != nil {\n\t\t\treturn container.RestartPolicy{}, errors.New(\"invalid restart policy format: maximum retry count must be an integer\")\n\t\t}\n\t\tretryCount = c\n\t}\n\n\treturn container.RestartPolicy{\n\t\tName:              container.RestartPolicyMode(name),\n\t\tMaximumRetryCount: retryCount,\n\t}, nil\n}\n","sourceCodeStart":71,"sourceCodeEnd":106,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/parse.go#L71-L106","documentation":"Thrown by opts.ParseRestartPolicy when strings.Cut finds a colon but the part before it is empty, e.g. \":5\". The policy name (no|always|on-failure|unless-stopped) must precede the optional \":retryCount\"; a leading colon means no policy name was provided.","triggerScenarios":"Calling opts.ParseRestartPolicy(\":3\"), or passing --restart=\":5\" on docker run/create.","commonSituations":"Building the restart policy string from a variable where the name component is empty (e.g. POLICY=\"\"; docker run --restart=\"$POLICY:5\"), or a stray leading colon typo.","solutions":["Provide a valid policy name before the colon: no, always, on-failure, or unless-stopped.","If you want the default, omit --restart entirely or use the empty string (which ParseRestartPolicy treats as zero-value/no-policy).","Guard against an empty name when composing the string."],"exampleFix":"// before\n_, _ = opts.ParseRestartPolicy(\":5\")\n// after\n_, _ = opts.ParseRestartPolicy(\"on-failure:5\")","handlingStrategy":"validation","validationCode":"validPolicies := map[string]bool{\"no\": true, \"always\": true, \"on-failure\": true, \"unless-stopped\": true}\nname, _, _ := strings.Cut(policy, \":\")\nif strings.Contains(policy, \":\") && !validPolicies[name] {\n    return fmt.Errorf(\"restart policy name %q is empty or invalid\", name)\n}\n_, err := opts.ParseRestartPolicy(policy)","typeGuard":null,"tryCatchPattern":"rp, err := opts.ParseRestartPolicy(policy)\nif err != nil {\n    return err\n}","preventionTips":["Always put the policy name before the colon.","Compose the string from validated name and integer count fields."],"tags":["restart-policy","validation","opts"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}