{"record":{"id":"d28a304f6c9219cc","repo":"docker/cli","slug":"invalid-field-s-must-be-a-key-value-pair-d28a30","errorCode":null,"errorMessage":"invalid field '%s' must be a key=value pair","messagePattern":"invalid field '(.+?)' must be a key=value pair","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/mount.go","lineNumber":63,"sourceCode":"\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\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"invalid field '%s' must be a key=value pair\", field)\n\t\t\t}\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"type\":\n\t\t\tmount.Type = mounttypes.Type(strings.ToLower(val))\n\t\tcase \"source\", \"src\":\n\t\t\tmount.Source = val\n\t\t\tif !filepath.IsAbs(val) && strings.HasPrefix(val, \".\") {\n\t\t\t\tif abs, err := filepath.Abs(val); err == nil {\n\t\t\t\t\tmount.Source = abs\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"target\", \"dst\", \"destination\":\n\t\t\tmount.Target = val\n\t\tcase \"readonly\", \"ro\":\n\t\t\tmount.ReadOnly, err = parseBoolValue(key, val, hasValue)\n\t\t\tif err != nil {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/mount.go#L45-L81","documentation":"Returned by MountOpt.Set (opts/mount.go:63) for a comma-separated mount field that has no '=' and is not one of the recognized bare-boolean toggles (readonly, ro, volume-nocopy, bind-nonrecursive, bind-create-src). Every non-boolean option must be expressed as key=value; a bare word that isn't whitelisted is treated as a malformed field.","triggerScenarios":"Passing a bare token like `readonly` is fine, but `source`, `target`, `tmpfs-size`, `consistency`, or any value-bearing option written without `=value` triggers this. Also fires for typos of a boolean name (e.g. `read-only`, `readnoly`).","commonSituations":"Writing `--mount type=volume,source,target=/data` (forgot source value), using a hyphenated variant like `read-only`, or assuming a flag name exists as a bare toggle when it requires a value.","solutions":["Convert the field to key=value, e.g. source=/data.","If you meant a boolean toggle, use the exact spelling: readonly, ro, volume-nocopy, bind-nonrecursive, or bind-create-src.","Check the field name spelling against the supported options list."],"exampleFix":"// before\n--mount \"type=bind,source,target=/data,readonly\"\n\n// after\n--mount \"type=bind,source=/data,target=/data,readonly\"","handlingStrategy":"validation","validationCode":"var mountBoolToggles = map[string]bool{\"readonly\": true, \"ro\": true, \"volume-nocopy\": true, \"bind-nonrecursive\": true, \"bind-create-src\": true}\n\n// validateBareFields checks that any '='-less field is a known boolean toggle.\nfunc validateBareFields(spec 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        if !strings.Contains(f, \"=\") && !mountBoolToggles[strings.ToLower(f)] {\n            return fmt.Errorf(\"field %q must be key=value or a known boolean toggle\", f)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := m.Set(spec); err != nil {\n    return fmt.Errorf(\"mount %q: %w\", spec, err)\n}","preventionTips":["Use key=value for any option that takes a value.","Keep a list of accepted bare toggles next to your mount builder.","Lint for typos like read-only in favor of readonly."],"tags":["mount","docker","csv","boolean","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}