{"record":{"id":"23ca5a9451e9ce28","repo":"argoproj/argo-workflows","slug":"maxdelay-cannot-be-less-than-0","errorCode":null,"errorMessage":"maxDelay cannot be less than 0","messagePattern":"maxDelay cannot be less than 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/sqldb/session.go","lineNumber":68,"sourceCode":"\tKubectlConfig kubernetes.Interface\n\tNamespace     string\n\tDBConfig      config.DBConfig\n\tUsername      string\n\tPassword      string\n\tMaxRetries    int\n\tBaseDelay     time.Duration\n\tMaxDelay      time.Duration\n}\n\nfunc validateProxyParams(proxy *SessionProxy) error {\n\tif proxy.maxRetries < 0 {\n\t\treturn fmt.Errorf(\"maxRetries cannot be less than 0\")\n\t}\n\tif proxy.baseDelay < 0 {\n\t\treturn fmt.Errorf(\"baseDelay cannot be less than 0\")\n\t}\n\tif proxy.maxDelay < 0 {\n\t\treturn fmt.Errorf(\"maxDelay cannot be less than 0\")\n\t}\n\tif proxy.retryMultiple < 0 {\n\t\treturn fmt.Errorf(\"retryMultiple cannot be less than 0\")\n\t}\n\treturn nil\n}\n\n// NewSessionProxy creates a new SessionProxy with the given configuration\nfunc NewSessionProxy(ctx context.Context, config SessionProxyConfig) (*SessionProxy, error) {\n\tdbType := dbTypeFromConfig(&config.DBConfig)\n\tproxy := &SessionProxy{\n\t\tkubectlConfig: config.KubectlConfig,\n\t\tnamespace:     config.Namespace,\n\t\tdbConfig:      &config.DBConfig,\n\t\tusername:      config.Username,\n\t\tpassword:      config.Password,\n\t\tdbType:        dbType,\n\t\tmaxRetries:    config.MaxRetries,","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/util/sqldb/session.go#L50-L86","documentation":"validateProxyParams rejects a negative maxDelay, the ceiling on exponential backoff between reconnection attempts. A negative ceiling breaks the backoff algorithm, so NewSessionProxy fails fast with this message. Pure input validation.","triggerScenarios":"Calling NewSessionProxy with SessionProxyConfig.MaxDelay < 0, or DBConfig.DBReconnectConfig.MaxDelaySeconds < 0 (converted to a negative time.Duration before validation).","commonSituations":"Negative maxDelaySeconds in the workflow-controller persistence config; YAML parsing quirks or human typo when hand-editing the controller ConfigMap; generated config where a subtraction went negative.","solutions":["Set MaxDelay (or DBReconnectConfig.MaxDelaySeconds) to 0 or positive — 0 falls back to the default 30s.","Fix the negative value in the dbReconnectConfig.maxDelaySeconds config entry.","Ensure maxDelay is not unintentionally below baseDelay when computing both from one expression.","If MaxDelay is derived at runtime, clamp: if d < 0 { d = 0 }."],"exampleFix":"// before\nSessionProxyConfig{MaxDelay: -30 * time.Second}\n// after\nSessionProxyConfig{MaxDelay: 30 * time.Second}","handlingStrategy":"validation","validationCode":"if cfg.MaxDelay < 0 {\n    return fmt.Errorf(\"MaxDelay must be >= 0, got %s\", cfg.MaxDelay)\n}\nif cfg.BaseDelay >= 0 && cfg.MaxDelay >= 0 && cfg.MaxDelay < cfg.BaseDelay {\n    return fmt.Errorf(\"MaxDelay should not be smaller than BaseDelay\")\n}","typeGuard":null,"tryCatchPattern":"if err := NewSessionProxy(ctx, cfg); err != nil {\n    if strings.Contains(err.Error(), \"maxDelay cannot be less than 0\") {\n        cfg.MaxDelay = 0 // triggers 30s default\n        return NewSessionProxy(ctx, cfg)\n    }\n    return err\n}","preventionTips":["Enforce baseDelay <= maxDelay in config validation.","Use typed config structs with clamping setters.","Test config rendering in CI before rollout.","Omit the field to accept the 30s default."],"tags":["validation","database","configuration"],"backgroundTag":"invalid-argument-value","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"}