{"record":{"id":"6cb8257839119508","repo":"docker/cli","slug":"invalid-option-s-in-s-option-should-not-hav","errorCode":null,"errorMessage":"invalid option '%s' in '%s': option should not have whitespace","messagePattern":"invalid option '(.+?)' in '(.+?)': option should not have whitespace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/mount.go","lineNumber":43,"sourceCode":"\tvalue = strings.TrimSpace(value)\n\tif value == \"\" {\n\t\treturn errors.New(\"value is empty\")\n\t}\n\n\tcsvReader := csv.NewReader(strings.NewReader(value))\n\tfields, err := csvReader.Read()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmount := mounttypes.Mount{\n\t\tType: mounttypes.TypeVolume, // default to volume mounts\n\t}\n\n\tfor _, field := range fields {\n\t\tkey, val, hasValue := strings.Cut(field, \"=\")\n\t\tif k := strings.TrimSpace(key); k != key {\n\t\t\treturn fmt.Errorf(\"invalid option '%s' in '%s': option should not have whitespace\", k, field)\n\t\t}\n\t\tif hasValue {\n\t\t\tv := strings.TrimSpace(val)\n\t\t\tif v == \"\" {\n\t\t\t\treturn fmt.Errorf(\"invalid value for '%s': value is empty\", key)\n\t\t\t}\n\t\t\tif v != val {\n\t\t\t\treturn fmt.Errorf(\"invalid value for '%s' in '%s': value should not have whitespace\", key, field)\n\t\t\t}\n\t\t}\n\n\t\t// TODO(thaJeztah): these options should not be case-insensitive.\n\t\tkey = strings.ToLower(key)\n\n\t\tif !hasValue {\n\t\t\tswitch key {\n\t\t\tcase \"readonly\", \"ro\", \"volume-nocopy\", \"bind-nonrecursive\", \"bind-create-src\":\n\t\t\t\t// boolean values","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/mount.go#L25-L61","documentation":"Returned by MountOpt.Set (opts/mount.go:43) when a mount option key has leading or trailing whitespace. After splitting a CSV field on '=', the code compares the raw key against its TrimSpace'd form; any difference (spaces/tabs around the key) is rejected because option keys must be clean identifiers.","triggerScenarios":"Passing a `--mount` CSV like `type=volume, source=foo` (space after comma), `src =foo`, or `\\ttype=volume`. The csv.Reader preserves intra-field whitespace, so ` src=foo` yields key ` src` which fails the equality check.","commonSituations":"Adding spaces after commas for readability in shell/compose, tabs from a pasted snippet, or trailing whitespace inside a quoted CSV field.","solutions":["Remove all whitespace around option keys: type=volume,source=foo.","Do not pad after commas; the CSV parser keeps those spaces as part of the next key.","If you need spaces in a value, wrap the whole --mount argument in quotes but keep keys unspaced.","Check for stray tabs/copied non-breaking spaces from documentation."],"exampleFix":"// before\n--mount \"type=volume, source=mydata, target=/data\"\n\n// after\n--mount \"type=volume,source=mydata,target=/data\"","handlingStrategy":"validation","validationCode":"// sanitizeMountSpec trims field separators so keys stay clean for MountOpt.Set.\nfunc sanitizeMountSpec(spec string) (string, error) {\n    r := csv.NewReader(strings.NewReader(spec))\n    fields, err := r.Read()\n    if err != nil {\n        return \"\", err\n    }\n    for _, f := range fields {\n        key, _, _ := strings.Cut(f, \"=\")\n        if strings.TrimSpace(key) != key {\n            return \"\", fmt.Errorf(\"key %q has surrounding whitespace\", key)\n        }\n    }\n    return spec, nil\n}","typeGuard":null,"tryCatchPattern":"var m opts.MountOpt\nif err := m.Set(spec); err != nil {\n    return fmt.Errorf(\"invalid mount %q: %w\", spec, err)\n}","preventionTips":["Never pad after commas in --mount CSV.","Generate mount strings from a typed struct rather than concatenation.","Lint mount specs in CI for whitespace around keys."],"tags":["mount","docker","csv","whitespace","parse","configuration"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}