{"record":{"id":"0bdc6d098ac9fc87","repo":"argoproj/argo-workflows","slug":"authsupplier-cannot-be-empty-when-connecting-to-ar","errorCode":null,"errorMessage":"AuthSupplier cannot be empty when connecting to Argo Server","messagePattern":"AuthSupplier cannot be empty when connecting to Argo Server","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiclient/apiclient.go","lineNumber":78,"sourceCode":"\t\t}\n\t\tlogFormat, err := logging.TypeFromStringOr(opts.LogFormat, logging.Text)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tlog = logging.NewSlogLogger(logLevel, logFormat)\n\t\tctx = logging.WithLogger(ctx, log)\n\t}\n\tlog.WithField(\"opts\", opts).Debug(ctx, \"Client options\")\n\tif opts.Offline {\n\t\treturn newOfflineClient(ctx, opts.OfflineFiles)\n\t}\n\tif opts.ArgoServerOpts.URL != \"\" && opts.InstanceID != \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"cannot use instance ID with Argo Server\")\n\t}\n\tswitch {\n\tcase opts.ArgoServerOpts.HTTP1:\n\t\tif opts.AuthSupplier == nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"AuthSupplier cannot be empty when connecting to Argo Server\")\n\t\t}\n\t\treturn newHTTP1Client(ctx, opts.ArgoServerOpts, opts.AuthSupplier(), opts.Proxy)\n\tcase opts.ArgoServerOpts.URL != \"\":\n\t\tif opts.AuthSupplier == nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"AuthSupplier cannot be empty when connecting to Argo Server\")\n\t\t}\n\t\treturn newArgoServerClient(ctx, opts.ArgoServerOpts, opts.AuthSupplier())\n\tdefault:\n\t\tif opts.ClientConfigSupplier != nil {\n\t\t\topts.ClientConfig = opts.ClientConfigSupplier()\n\t\t}\n\t\treturn newArgoKubeClient(ctx, opts.ArgoKubeOpts, opts.ClientConfig, instanceid.NewService(opts.InstanceID))\n\t}\n}\n","sourceCodeStart":60,"sourceCodeEnd":93,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/pkg/apiclient/apiclient.go#L60-L93","documentation":"When connecting over HTTP1 to the Argo Server (opts.ArgoServerOpts.HTTP1, used for HTTP fallback / proxies / event streams), the client authenticates using a caller-supplied AuthSupplier. There is no default credential source in this mode, so a nil AuthSupplier is rejected rather than producing an unauthenticated client.","triggerScenarios":"NewClientFromOptsWithContext with Opts{ArgoServerOpts: {URL: ..., HTTP1: true}} and AuthSupplier nil — e.g. constructing Opts by hand without the wiring the CLI normally performs (which sets AuthSupplier from the k8s token/SSO).","commonSituations":"Custom Go programs using pkg/apiclient with HTTP1 enabled; environments where ARGO_TOKEN/auth wiring was skipped; testing HTTP1 mode directly without replicating the CLI's auth setup.","solutions":["Set Opts.AuthSupplier to a func returning your auth token (e.g. () -> \"Bearer <token>\")","If using the argo CLI, don't hand-build Opts — use the CLI's client factory which supplies auth automatically","If you only need the gRPC path, clear HTTP1 and set URL with AuthSupplier or use ClientConfigSupplier for direct-kube"],"exampleFix":"// before\nopts := apiclient.Opts{ArgoServerOpts: apiclient.ArgoServerOpts{URL: url, HTTP1: true}}\n// after\nopts := apiclient.Opts{ArgoServerOpts: apiclient.ArgoServerOpts{URL: url, HTTP1: true}, AuthSupplier: func() string { return token }}","handlingStrategy":"validation","validationCode":"func newHTTP1Opts(url, token string) (apiclient.Opts, error) {\n    if token == \"\" {\n        return apiclient.Opts{}, errors.New(\"token required for HTTP1 Argo Server access (set ARGO_TOKEN)\")\n    }\n    return apiclient.Opts{\n        ArgoServerOpts: apiclient.ArgoServerOpts{URL: url, HTTP1: true},\n        AuthSupplier:   func() string { return \"Bearer \" + token },\n    }, nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check Opts.AuthSupplier != nil in a buildOpts helper before calling the library","Load the token from ARGO_TOKEN or SSO in one shared factory","Write an integration smoke test that constructs the client early at startup"],"tags":["grpc","authentication","configuration","client"],"backgroundTag":"missing-auth-supplier","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"}