argoproj/argo-workflows · error
not supported when you are in offline mode
Error message
not supported when you are in offline mode
What it means
ErrOffline is the sentinel error returned by every unsupported operation of the offline API client. The offline client exists so `argo lint` and the offline apiclient transport can validate files without a cluster; it only stores WorkflowTemplates/ClusterWorkflowTemplates in memory. Any service method outside that scope (cluster workflow template writes, cron workflow creation, etc.) deliberately fails with this error instead of connecting.
Source
Thrown at pkg/apiclient/offline-client.go:39
func (m offlineWorkflowTemplateGetterMap) GetNamespaceGetter(namespace string) templateresolution.WorkflowTemplateNamespacedGetter {
v := m[namespace]
if v == nil {
return offlineWorkflowTemplateNamespacedGetter{
workflowTemplates: map[string]*wfv1.WorkflowTemplate{},
namespace: namespace,
}
}
return m[namespace]
}
type offlineClient struct {
clusterWorkflowTemplateGetter templateresolution.ClusterWorkflowTemplateGetter
namespacedWorkflowTemplateGetterMap offlineWorkflowTemplateGetterMap
}
var ErrOffline = fmt.Errorf("not supported when you are in offline mode")
var _ Client = &offlineClient{}
// newOfflineClient creates a client that keeps all files (or files recursively contained within a path) given to it in memory.
// It is useful for linting a set of files without having to connect to a cluster.
func newOfflineClient(ctx context.Context, paths []string) (context.Context, Client, error) {
clusterWorkflowTemplateGetter := &offlineClusterWorkflowTemplateGetter{
clusterWorkflowTemplates: map[string]*wfv1.ClusterWorkflowTemplate{},
}
workflowTemplateGetters := offlineWorkflowTemplateGetterMap{}
for _, basePath := range paths {
err := file.WalkManifests(ctx, basePath, func(path string, bytes []byte) error {
for _, pr := range common.ParseObjects(ctx, bytes, false) {
obj, err := pr.Object, pr.Err
if err != nil {
return fmt.Errorf("failed to parse YAML from file %s: %w", path, err)
}
View on GitHub (pinned to 35bff19146)
Solutions
- Do not call cluster-workflow-template or cron-workflow operations through an offline client; use a real client (argo server gRPC or direct-kube transport) for those operations.
- Restructure the lint/validate path to only rely on template resolution (templateresolution uses the in-memory getters), not full service clients.
- If you need to detect this case programmatically, compare the returned error against pkg/apiclient.ErrOffline with errors.Is before falling back to a connected client.
Example fix
// before
wfTmpl, err := cwftClient.Get(ctx, req) // offline client -> ErrOffline
// after
if errors.Is(err, apiclient.ErrOffline) {
// resolve template locally via templateresolution instead of RPC
tmpl, err := templateGetter.Get(ctx, req)
} Defensive patterns
Strategy: try-catch
Validate before calling
if client is apiclient.Client {
_, err := cwftClient.ListClusterWorkflowTemplates(ctx, nil)
if errors.Is(err, apiclient.ErrOffline) {
// switch to a connected client before doing cluster-template ops
}
} Type guard
func isOfflineErr(err error) bool {
return errors.Is(err, apiclient.ErrOffline)
} Try / catch
tmpl, err := cwftClient.GetClusterWorkflowTemplate(ctx, req)
if err != nil {
if errors.Is(err, apiclient.ErrOffline) {
tmpl, err = localTemplateGetter.Get(ctx, req.Name)
}
if err != nil { return err }
} Prevention
- Only use the offline client for lint/validate flows; construct a server or direct-kube client for CRUD operations.
- Check errors.Is(err, apiclient.ErrOffline) whenever the transport of your client may vary.
- Keep cluster-template/cron-workflow code paths out of offline lint tooling.
When it happens
Trigger: Calling CreateClusterWorkflowTemplate, GetClusterWorkflowTemplate, ListClusterWorkflowTemplates, UpdateClusterWorkflowTemplate, DeleteClusterWorkflowTemplate, or CreateCronWorkflow on an OfflineClusterWorkflowTemplateServiceClient, which is what the apiclient returns when the client is constructed in offline mode (e.g. `argo lint` or apiclient's offline transport).
Common situations: Running `argo lint` on files that contain ClusterWorkflowTemplates or CronWorkflows and invoking code paths that try to fetch/create those resources; reusing an offline-constructed client for operations it was never meant to perform; tests or tools built on pkg/apiclient that assume a live server.
Related errors
- duplicate ClusterWorkflowTemplate found: %q
- duplicate WorkflowTemplate found: %q
- couldn't find workflow template %q in namespace %q
- failed to parse YAML from file %s: %w
- couldn't find cluster workflow template %q
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/36502f3dd57d60fd.
Report an issue: GitHub.