argoproj/argo-workflows · error

failed to parse YAML from file %s: %w

Error message

failed to parse YAML from file %s: %w

What it means

When building the in-memory template store for the offline client, argo walks the given paths and parses every YAML/JSON manifest. If any document fails to parse into a Kubernetes object, the walk is aborted and this wrapped error (with the offending file path) is returned from newOfflineClient.

Source

Thrown at pkg/apiclient/offline-client.go:55

}

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)
				}

				if obj == nil {
					continue // could not parse to kubernetes object
				}

				objName := obj.GetName()
				namespace := obj.GetNamespace()

				switch v := obj.(type) {
				case *wfv1.ClusterWorkflowTemplate:
					if _, ok := clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName]; ok {
						return fmt.Errorf("duplicate ClusterWorkflowTemplate found: %q", objName)
					}
					clusterWorkflowTemplateGetter.clusterWorkflowTemplates[objName] = v

				case *wfv1.WorkflowTemplate:
					getter, ok := workflowTemplateGetters[namespace]

View on GitHub (pinned to 35bff19146)

Solutions

  1. Open the file named in the message and fix the YAML syntax error reported by the wrapped parse error.
  2. Run `yamllint` or a YAML parser on the file to pinpoint the broken document.
  3. Split multi-document files and validate each document individually to find the failing one.

Example fix

// before (broken YAML)
metadata:
  name: tmpl
 spec:
   templates: []
// after
metadata:
  name: tmpl
spec:
  templates: []
Defensive patterns

Strategy: validation

Validate before calling

import "sigs.k8s.io/yaml"
func validateYAMLFile(path string) error {
    b, err := os.ReadFile(path)
    if err != nil { return err }
    var out []map[string]any
    return yaml.Unmarshal(b, &out)
}

Try / catch

client, err := apiclient.NewOfflineClient(ctx, paths)
if err != nil {
    var pathErr *fs.PathError
    if strings.Contains(err.Error(), "failed to parse YAML from file") {
        // surface err to the user: fix the YAML in the named file
    }
    return err
}

Prevention

When it happens

Trigger: Running `argo lint` / creating an offline client over a path containing a file whose YAML is malformed, has bad indentation, or contains a document that common.ParseObjects cannot parse into a k8s object (pr.Err non-nil).

Common situations: Hand-edited manifest with a YAML typo; a file with mixed tabs/spaces; multi-doc file where one document is broken; passing a directory that includes generated or partial files that are not valid manifests.

Understand the failure class

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/205056844ec58a6b. Report an issue: GitHub.