{"record":{"id":"30e124679cb550cb","repo":"argoproj/argo-workflows","slug":"notfound-30e124","errorCode":"NotFound","errorMessage":"key %s not found in configmap %s/%s","messagePattern":"key (.+?) not found in configmap (.+?)/(.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/sync/sync_cm.go","lineNumber":91,"sourceCode":"}\n\nfunc (s *configMapSyncProvider) getSyncLimit(ctx context.Context, req *syncpkg.GetSyncLimitRequest) (*syncpkg.SyncLimitResponse, error) {\n\tif err := checkConfigMapPermission(ctx, \"get\", req.Namespace); err != nil {\n\t\treturn nil, err\n\t}\n\n\tkubeClient := auth.GetKubeClient(ctx)\n\n\tconfigmapGetter := kubeClient.CoreV1().ConfigMaps(req.Namespace)\n\n\tcm, err := configmapGetter.Get(ctx, req.CmName, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn nil, sutils.ToStatusError(err, codes.Internal)\n\t}\n\n\tlimit, ok := cm.Data[req.Key]\n\tif !ok {\n\t\treturn nil, sutils.ToStatusError(fmt.Errorf(\"key %s not found in configmap %s/%s\", req.Key, cm.Namespace, cm.Name), codes.NotFound)\n\t}\n\n\tparsedLimit, err := strconv.Atoi(limit)\n\tif err != nil {\n\t\treturn nil, sutils.ToStatusError(fmt.Errorf(\"invalid limit format for key %s in configmap %s/%s\", req.Key, cm.Namespace, cm.Name), codes.InvalidArgument)\n\t}\n\n\treturn &syncpkg.SyncLimitResponse{\n\t\tCmName:    cm.Name,\n\t\tNamespace: cm.Namespace,\n\t\tKey:       req.Key,\n\t\tLimit:     int32(parsedLimit),\n\t\tType:      syncpkg.SyncConfigType_CONFIGMAP,\n\t}, nil\n}\n\nfunc (s *configMapSyncProvider) updateSyncLimit(ctx context.Context, req *syncpkg.UpdateSyncLimitRequest) (*syncpkg.SyncLimitResponse, error) {\n\tif req.Limit <= 0 {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/sync/sync_cm.go#L73-L109","documentation":"GetSyncLimit reads the limit value from the configmap and errors with NotFound when the requested key is absent from cm.Data. This distinguishes 'configmap exists but key missing' from other failures.","triggerScenarios":"GetSyncLimit with a Key that was never written to the configmap, or after the key was deleted/renamed while the configmap itself still exists.","commonSituations":"Typo in the key name, configmap shared by multiple limits where only some keys exist, workflow semaphore config referencing a key the operator never created.","solutions":["Create the key in the configmap (via CreateSyncLimit or kubectl edit) before getting it","Verify the key name spelling and namespace in the request","List the configmap data (kubectl get cm <name> -o yaml) to confirm which keys exist"],"exampleFix":"// before\nkubectl get cm my-cm -n ns  # key 'parallelism' missing\n// after\nkubectl create cm my-cm -n ns --from-literal=parallelism=5","handlingStrategy":"try-catch","validationCode":"cm, _ := kube.CoreV1().ConfigMaps(ns).Get(ctx, name, metav1.GetOptions{})\nif cm != nil { if _, ok := cm.Data[key]; !ok { return fmt.Errorf(\"key %s missing\", key) } }","typeGuard":null,"tryCatchPattern":"_, err := client.GetSyncLimit(ctx, req)\nif st, ok := status.FromError(err); ok && st.Code() == codes.NotFound {\n    // provision then retry: client.CreateSyncLimit(...)\n}","preventionTips":["Confirm key names against the workflow semaphore config before lookup","Create limits as part of namespace bootstrap","Use consistent naming constants for limit keys"],"tags":["grpc","sync-limit","configmap","not-found"],"backgroundTag":"key-not-found","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"}