{"record":{"id":"f061a3972f2d919a","repo":"docker/cli","slug":"invalid-spec-s-w","errorCode":null,"errorMessage":"invalid spec: %s: %w","messagePattern":"invalid spec: (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/volumespec/volumespec.go","lineNumber":40,"sourceCode":"\n\tswitch len(spec) {\n\tcase 0:\n\t\treturn volume, errors.New(\"invalid empty volume spec\")\n\tcase 1, 2:\n\t\tvolume.Target = spec\n\t\tvolume.Type = string(mount.TypeVolume)\n\t\treturn volume, nil\n\t}\n\n\tbuffer := make([]rune, 0, len(spec))\n\tfor _, char := range spec + string(endOfSpec) {\n\t\tswitch {\n\t\tcase isWindowsDrive(buffer, char):\n\t\t\tbuffer = append(buffer, char)\n\t\tcase char == ':' || char == endOfSpec:\n\t\t\tif err := populateFieldFromBuffer(char, buffer, &volume); err != nil {\n\t\t\t\tpopulateType(&volume)\n\t\t\t\treturn volume, fmt.Errorf(\"invalid spec: %s: %w\", spec, err)\n\t\t\t}\n\t\t\tbuffer = buffer[:0] // reset, but reuse capacity\n\t\tdefault:\n\t\t\tbuffer = append(buffer, char)\n\t\t}\n\t}\n\n\tpopulateType(&volume)\n\treturn volume, nil\n}\n\nfunc isWindowsDrive(buffer []rune, char rune) bool {\n\treturn char == ':' && len(buffer) == 1 && unicode.IsLetter(buffer[0])\n}\n\nfunc populateFieldFromBuffer(char rune, buffer []rune, volume *VolumeConfig) error {\n\tstrBuffer := string(buffer)\n\tswitch {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/internal/volumespec/volumespec.go#L22-L58","documentation":"Parse fails when populateFieldFromBuffer returns an error while splitting the spec on ':' — specifically \"empty section between colons\" (e.g. \"a::b\" or a leading/trailing colon) or \"too many colons\" (more than three colon-separated sections). The wrapped error names which rule was broken.","triggerScenarios":"A volume mount spec with an empty field between colons or more than three colon-separated parts, e.g. -v a::b, -v /s:/d:ro:extra, or a stray leading colon.","commonSituations":"Typing -v with extra colons; Windows absolute paths confusing the splitter; forgetting source or target; mixing option syntax.","solutions":["Count the colons: at most src:dst:options (3 sections).","Ensure no section is empty (no leading/trailing/double colons).","For complex mounts, switch to the --mount type=... syntax which is unambiguous.","On Windows, use the proper drive-letter form or --mount to avoid path/colon ambiguity."],"exampleFix":"# before\ndocker run -v /data::/data myimg        # empty section\n\n# after\ndocker run -v /data:/data:ro myimg\n# or, unambiguous:\ndocker run --mount type=bind,source=/data,destination=/data,readonly myimg","handlingStrategy":"validation","validationCode":"// Lightweight pre-check for the common colon mistakes.\nfunc looksLikeValidSpec(s string) error {\n    parts := strings.Split(s, \":\")\n    if len(parts) > 3 {\n        return fmt.Errorf(\"too many colons in %q\", s)\n    }\n    for _, p := range parts {\n        if p == \"\" {\n            return fmt.Errorf(\"empty section between colons in %q\", s)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer the --mount type=... syntax for anything non-trivial.","Count colons (max 3) and avoid empty sections.","Handle Windows paths explicitly or via --mount to avoid colon ambiguity.","Validate user-supplied -v specs at the input boundary."],"tags":["docker","volumes","parsing","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}