{"record":{"id":"4af858c7caa4c1db","repo":"docker/cli","slug":"invalid-value-for-s-invalid-boolean-value-q","errorCode":null,"errorMessage":"invalid value for '%s': invalid boolean value (%q): must be one of \"true\", \"1\", \"false\", or \"0\" (default \"true\")","messagePattern":"invalid value for '(.+?)': invalid boolean value \\(%q\\): must be one of \"true\", \"1\", \"false\", or \"0\" \\(default \"true\"\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/mount_utils.go","lineNumber":85,"sourceCode":"\treturn nil\n}\n\n// parseBoolValue returns the boolean value represented by the string. It returns\n// true if no value is set.\n//\n// It is similar to [strconv.ParseBool], but only accepts 1, true, 0, false.\n// Any other value returns an error.\nfunc parseBoolValue(key string, val string, hasValue bool) (bool, error) {\n\tif !hasValue {\n\t\treturn true, nil\n\t}\n\tswitch val {\n\tcase \"1\", \"true\":\n\t\treturn true, nil\n\tcase \"0\", \"false\":\n\t\treturn false, nil\n\tdefault:\n\t\treturn false, fmt.Errorf(`invalid value for '%s': invalid boolean value (%q): must be one of \"true\", \"1\", \"false\", or \"0\" (default \"true\")`, key, val)\n\t}\n}\n\nfunc ensureVolumeOptions(m *mount.Mount) *mount.VolumeOptions {\n\tif m.VolumeOptions == nil {\n\t\tm.VolumeOptions = &mount.VolumeOptions{}\n\t}\n\treturn m.VolumeOptions\n}\n\nfunc ensureVolumeDriver(m *mount.Mount) *mount.Driver {\n\tensureVolumeOptions(m)\n\tif m.VolumeOptions.DriverConfig == nil {\n\t\tm.VolumeOptions.DriverConfig = &mount.Driver{}\n\t}\n\treturn m.VolumeOptions.DriverConfig\n}\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/mount_utils.go#L67-L103","documentation":"Returned by parseBoolValue (opts/mount_utils.go:85) when a mount boolean option (readonly/ro, volume-nocopy, bind-create-src) is given a value that isn't one of the four accepted literals: true, 1, false, 0. Unlike strconv.ParseBool, this parser does not accept t/f/T/F/yes/no. When the option has no '=' (bare toggle), it defaults to true and never reaches this error.","triggerScenarios":"Passing `readonly=yes`, `readonly=on`, `volume-nocopy=True` (capital T), `ro=enabled`, or any non-canonical boolean spelling in a --mount CSV.","commonSituations":"Using yes/no or True/False from compose/JSON, or assuming Go's broader ParseBool vocabulary applies.","solutions":["Use one of true, 1, false, 0 (lowercase).","For a plain on-switch, omit the value entirely: readonly (defaults to true).","Normalize booleans in generated mount strings before parsing."],"exampleFix":"// before\n--mount \"type=bind,source=/d,target=/d,readonly=yes\"\n\n// after\n--mount \"type=bind,source=/d,target=/d,readonly=true\"","handlingStrategy":"validation","validationCode":"var mountBoolValues = map[string]bool{\"true\": true, \"1\": true, \"false\": true, \"0\": true}\n\nfunc validateMountBool(key, val string, hasValue bool) error {\n    if !hasValue {\n        return nil // defaults to true\n    }\n    if !mountBoolValues[val] {\n        return fmt.Errorf(\"%s must be true/1/false/0, got %q\", key, val)\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":["Normalize booleans to true/1/false/0 before emitting mount CSV.","For toggles, prefer omitting the value.","Reject yes/no/on/off in your mount builder."],"tags":["mount","docker","boolean","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}