{"record":{"id":"b91df51cb2e7f778","repo":"argoproj/argo-workflows","slug":"if-you-have-an-item-in-your-config-map-named-conf","errorCode":null,"errorMessage":"if you have an item in your config map named 'config', you must only have one item","messagePattern":"if you have an item in your config map named 'config', you must only have one item","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/controller.go","lineNumber":43,"sourceCode":"\t// name of the config map\n\tconfigMap     string\n\tkubeclientset kubernetes.Interface\n}\n\nfunc NewController(namespace, name string, kubeclientset kubernetes.Interface) Controller {\n\treturn &controller{\n\t\tnamespace:     namespace,\n\t\tconfigMap:     name,\n\t\tkubeclientset: kubeclientset,\n\t}\n}\n\nfunc parseConfigMap(cm *apiv1.ConfigMap, config *Config) error {\n\t// The key in the configmap to retrieve workflow configuration from.\n\t// Content encoding is expected to be YAML.\n\trawConfig, ok := cm.Data[\"config\"]\n\tif ok && len(cm.Data) != 1 {\n\t\treturn fmt.Errorf(\"if you have an item in your config map named 'config', you must only have one item\")\n\t}\n\tif !ok {\n\t\tfor name, value := range cm.Data {\n\t\t\tif strings.Contains(value, \"\\n\") {\n\t\t\t\t// this mucky code indents with two spaces\n\t\t\t\trawConfig = rawConfig + name + \":\\n  \" + strings.Join(strings.Split(strings.Trim(value, \"\\n\"), \"\\n\"), \"\\n  \") + \"\\n\"\n\t\t\t} else {\n\t\t\t\trawConfig = rawConfig + name + \": \" + value + \"\\n\"\n\t\t\t}\n\t\t}\n\t}\n\terr := yaml.UnmarshalStrict([]byte(rawConfig), config)\n\treturn err\n}\n\nfunc (cc *controller) Get(ctx context.Context) (*Config, error) {\n\tcmClient := cc.kubeclientset.CoreV1().ConfigMaps(cc.namespace)\n\tcm, err := cmClient.Get(ctx, cc.configMap, metav1.GetOptions{})","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/config/controller.go#L25-L61","documentation":"parseConfigMap reads the workflow-controller-configmap. If a key literally named `config` exists, it must be the ONLY key, since `config` holds the entire YAML document while other keys are treated as individual top-level entries. Mixed usage is ambiguous, so it is rejected with this error.","triggerScenarios":"The configmap contains a `config` key plus at least one other key (len(cm.Data) != 1) when Parse/parseConfigMap runs, e.g. during controller startup or config reload.","commonSituations":"Operators adding a new setting as a separate key while the legacy single `config` YAML key is still present; leftover keys from Helm charts or tooling writing extra entries (tls, secrets-style keys) into the same configmap.","solutions":["Merge all configuration into the single `config` YAML key and delete the other keys from the configmap.","Alternatively migrate fully to per-key entries (the non-`config` style) and remove the `config` key.","Apply the corrected configmap with kubectl and let the controller reload it.","Audit chart/tooling that writes extra keys into workflow-controller-configmap and pin them to one of the two accepted formats."],"exampleFix":"// before\ndata:\n  config: |\n    containerRuntimeExecutor: emissary\n  links: |\n    ...\n// after\ndata:\n  config: |\n    containerRuntimeExecutor: emissary\n    links:\n      - ...","handlingStrategy":"validation","validationCode":"// validate configmap keys before apply\nkeys := listConfigMapKeys(\"workflow-controller-configmap\")\nif containsKey(keys, \"config\") && len(keys) > 1 {\n    return errors.New(\"key 'config' must be the only key in the configmap\")\n}","typeGuard":"func isLegacySingleKeyConfig(cm *apiv1.ConfigMap) bool {\n    _, ok := cm.Data[\"config\"]\n    return ok && len(cm.Data) == 1\n}","tryCatchPattern":"cfg, err := config.Parse(ctx, cm)\nif err != nil {\n    return nil, fmt.Errorf(\"invalid workflow-controller-configmap (merge everything into one 'config' key or all separate keys): %w\", err)\n}","preventionTips":["Pick one configmap format — single `config` YAML key OR per-key entries — and stick to it.","Audit Helm charts/operator manifests for extra keys written into the configmap.","Validate with `argo lint` or a dry-run before kubectl apply.","Document the format in your deployment tooling to prevent drift."],"tags":["config","controller","configmap"],"backgroundTag":"configmap-format-conflict","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}