{"record":{"id":"463208527b7491b6","repo":"kubernetes/kops","slug":"unhandled-field-q","errorCode":null,"errorMessage":"unhandled field: %q","messagePattern":"unhandled field: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/set_cluster.go","lineNumber":32,"sourceCode":"limitations under the License.\n*/\n\npackage commands\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tapi \"k8s.io/kops/pkg/apis/kops\"\n\t\"k8s.io/kops/util/pkg/reflectutils\"\n)\n\n// SetClusterFields sets field values in the cluster\nfunc SetClusterFields(fields []string, cluster *api.Cluster) error {\n\tfor _, field := range fields {\n\t\tkv := strings.SplitN(field, \"=\", 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn fmt.Errorf(\"unhandled field: %q\", field)\n\t\t}\n\n\t\tkey := kv[0]\n\t\tkey = strings.TrimPrefix(key, \"cluster.\")\n\n\t\tkey = api.InternalPathForClusterField(key)\n\n\t\tif err := reflectutils.SetString(cluster, key, kv[1]); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":14,"sourceCodeEnd":46,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/commands/set_cluster.go#L14-L46","documentation":"SetClusterFields parses each field argument as key=value; if a field has no '=' separator (SplitN yields 1 element) it returns 'unhandled field: %q'. It is a strict argument-format guard for the key=value field syntax used by create/edit cluster.","triggerScenarios":"Calling SetClusterFields with a slice entry like \"spec.kubernetesVersion\" (missing '=value'), e.g. `kops create cluster --set foo` without '='. TestSetClusterBadInput exercises exactly this.","commonSituations":"Typing `--set kubernetesVersion` instead of `--set kubernetesVersion=1.30.0`; quoting mistakes in shells that split values; mixing kubectl-style -l selectors with kops --set syntax.","solutions":["Ensure every field string contains '=' in the form key=value (e.g. cluster.spec.kubernetesVersion=1.30.0).","Quote the whole argument in the shell so spaces/'=' survive: --set \"spec.nodePortRange=30000-32767\".","Prefix cluster fields with 'cluster.' or 'spec.' as expected by api.InternalPathForClusterField."],"exampleFix":"// before\nfields := []string{\"spec.kubernetesVersion\"}\nerr := SetClusterFields(fields, cluster) // unhandled field: \"spec.kubernetesVersion\"\n// after\nfields := []string{\"spec.kubernetesVersion=1.30.4\"}\nerr := SetClusterFields(fields, cluster)","handlingStrategy":"validation","validationCode":"func validClusterFields(fields []string) error {\n\tfor _, f := range fields {\n\t\tif !strings.Contains(f, \"=\") {\n\t\t\treturn fmt.Errorf(\"field %q must be key=value\", f)\n\t\t}\n\t}\n\treturn nil\n}\n// call before SetClusterFields","typeGuard":"func isKeyValue(s string) bool {\n\tparts := strings.SplitN(s, \"=\", 2)\n\treturn len(parts) == 2 && parts[0] != \"\"\n}","tryCatchPattern":"if err := SetClusterFields(fields, cluster); err != nil {\n\tif strings.HasPrefix(err.Error(), \"unhandled field:\") {\n\t\tvar f string\n\t\tfmt.Sscanf(err.Error(), \"unhandled field: %q\", &f)\n\t\treturn fmt.Errorf(\"field %q missing '=value'; use key=value\", f)\n\t}\n\treturn err\n}","preventionTips":["Always quote --set values in shell: --set \"spec.nodePortRange=30000-32767\".","Sanity-check scripted field arrays for empty or truncated entries.","Follow the documented cluster. / spec. key prefixes.","Add unit tests with malformed inputs (TestSetClusterBadInput pattern) to catch regressions."],"tags":["kops","cli-input","argument-parsing"],"backgroundTag":"invalid-key-value-field-syntax","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}