{"record":{"id":"a6507474094fe53e","repo":"kubernetes/kubernetes","slug":"the-argument-must-have-both-a-key-and-a-value","errorCode":null,"errorMessage":"the argument must have both a key and a value","messagePattern":"the argument must have both a key and a value","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kubeadm/app/util/arguments.go","lineNumber":105,"sourceCode":"\treturn args\n}\n\n// parseArgument parses the argument \"--foo=bar\" to \"foo\" and \"bar\"\nfunc parseArgument(arg string) (string, string, error) {\n\tif !strings.HasPrefix(arg, \"--\") {\n\t\treturn \"\", \"\", errors.New(\"the argument should start with '--'\")\n\t}\n\tif !strings.Contains(arg, \"=\") {\n\t\treturn \"\", \"\", errors.New(\"the argument should have a '=' between the flag and the value\")\n\t}\n\t// Remove the starting --\n\targ = strings.TrimPrefix(arg, \"--\")\n\t// Split the string on =. Return only two substrings, since we want only key/value, but the value can include '=' as well\n\tkeyvalSlice := strings.SplitN(arg, \"=\", 2)\n\n\t// Make sure both a key and value is present\n\tif len(keyvalSlice) != 2 {\n\t\treturn \"\", \"\", errors.New(\"the argument must have both a key and a value\")\n\t}\n\tif len(keyvalSlice[0]) == 0 {\n\t\treturn \"\", \"\", errors.New(\"the argument must have a key\")\n\t}\n\n\treturn keyvalSlice[0], keyvalSlice[1], nil\n}\n\n// sortArgsSlice sorts a slice of Args alpha-numerically.\nfunc sortArgsSlice(argsPtr *[]kubeadmapi.Arg) {\n\targs := *argsPtr\n\tsort.Slice(args, func(i, j int) bool {\n\t\tif args[i].Name == args[j].Name {\n\t\t\treturn args[i].Value < args[j].Value\n\t\t}\n\t\treturn args[i].Name < args[j].Name\n\t})\n}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/kubernetes/kubernetes/blob/b882c60b4023bdf09264c2d5d30a2cadebc240fb/cmd/kubeadm/app/util/arguments.go#L87-L123","documentation":"Returned by parseArgument when, after stripping '--' and splitting on '=' with SplitN(.,=,2), the result does not yield exactly two parts. In practice this is guarded by the earlier '=' presence check, so it covers an edge-case where splitting still fails to produce a key/value pair.","triggerScenarios":"A token that passes the '--' prefix and '=' presence checks but SplitN(arg,'=',2) returns something other than two elements (defensive branch; rarely hit given the prior checks).","commonSituations":"Extremely unusual inputs; effectively a defensive guard. If hit, the token is structurally malformed despite containing '='.","solutions":["Rewrite the token in canonical '--key=value' form.","Remove stray characters/whitespace around the '=' in kubeadm-flags.env or extraArgs.","If reproducing, isolate the exact token and report it; this branch is defensive and seldom reached."],"exampleFix":"# before (malformed token)\nKUBELET_KUBEADM_ARGS=\"--=value\"\n# after\nKUBELET_KUBEADM_ARGS=\"--real-key=value\"","handlingStrategy":"validation","validationCode":"parts := strings.SplitN(strings.TrimPrefix(a, \"--\"), \"=\", 2)\nif len(parts) != 2 {\n    return fmt.Errorf(\"argument %q must have both key and value\", a)\n}","typeGuard":"func isKeyValuePair(a string) bool {\n    parts := strings.SplitN(strings.TrimPrefix(a, \"--\"), \"=\", 2)\n    return len(parts) == 2\n}","tryCatchPattern":null,"preventionTips":["Canonicalize all args to '--key=value' before persistence.","Reject malformed args at generation time rather than relying on parse-time warnings.","Add a config-lint step in CI for kubeadm-flags.env."],"tags":["kubeadm","arguments","flags","config"],"analyzedSha":"b882c60b4023bdf09264c2d5d30a2cadebc240fb","analyzedAt":"2026-08-07T04:07:48.144Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}