getsops/sops · error

Error while flattening metadata: %w

Error message

Error while flattening metadata: %w

What it means

Wrapper emitted by SerializeMetadata when flattenTreeBranch fails to flatten the metadata tree branch into flat key=value items (used when MetadataOpts.Flatten is not MetadataFlattenNone, i.e. env/dotenv-style stores). Flattening fails when the metadata branch contains nested structures that cannot be represented as flat keys.

Source

Thrown at stores/metadata.go:281

		return tb, nil
	}
	return nil, fmt.Errorf("Internal error: unexpected metadata conversion result %T", metadata)
}

// SerializeMetadata embeds the metadata of `data` into its tree branches.
func SerializeMetadata(data sops.Tree, opts MetadataOpts) (sops.TreeBranches, error) {
	md, err := metadataToTreeBranch(metadataFromInternal(data.Metadata))
	if err != nil {
		return nil, fmt.Errorf("Error while serializing metadata: %w", err)
	}
	if opts.Flatten != MetadataFlattenNone {
		var prefix string
		if opts.Flatten == MetadataFlattenFull {
			prefix = SopsPrefix
		}
		md, err = flattenTreeBranch(md, prefix)
		if err != nil {
			return nil, fmt.Errorf("Error while flattening metadata: %w", err)
		}
		if opts.EscapeNewlines {
			for i, item := range md {
				if value, ok := item.Value.(string); ok {
					md[i] = sops.TreeItem{
						Key:   item.Key,
						Value: strings.ReplaceAll(value, "\n", "\\n"),
					}
				}
			}
		}
	}
	if opts.Flatten != MetadataFlattenFull {
		md = sops.TreeBranch{
			sops.TreeItem{
				Key:   SopsMetadataKey,
				Value: md,
			},

View on GitHub (pinned to 13442bb981)

Solutions

  1. Inspect the wrapped flatten error for the offending metadata key
  2. Remove or normalize non-flattenable metadata fields in custom Metadata
  3. Use MetadataFlattenNone with a store that supports nested metadata (json/yaml) instead of env formats
  4. Let sops generate the metadata (via LoadEncryptedFile) rather than hand-building it

Example fix

// before
out, err := stores.SerializeMetadata(tree, stores.MetadataOpts{Flatten: stores.MetadataFlattenFull})
// after: use a format whose metadata doesn't need flattening, or keep none
out, err := stores.SerializeMetadata(tree, stores.MetadataOpts{Flatten: stores.MetadataFlattenNone})
Defensive patterns

Strategy: try-catch

Validate before calling

// only flatten for env-style stores; verify metadata is flat-friendly
func canFlatten(md sops.Metadata) bool {
	m, _ := stores.MetadataFromInternal(md) // must convert cleanly first
	_ = m
	return true // additionally verify no exotic custom fields
}

Try / catch

out, err := stores.SerializeMetadata(tree, opts)
if err != nil {
	if strings.HasPrefix(err.Error(), "Error while flattening metadata") {
		return fmt.Errorf("metadata cannot be flattened for this store; use MetadataFlattenNone with json/yaml store: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling SerializeMetadata with Flatten set to MetadataFlattenPartial or MetadataFlattenFull while the converted metadata branch contains values (nested maps/lists) that flattenTreeBranch cannot flatten — e.g. malformed or unexpectedly deep metadata structures from a hand-built Metadata.

Common situations: Writing dotenv/env-format encrypted files with custom or incomplete metadata, converting between store formats (json → env) where metadata shapes differ, custom metadata fields that flattenTreeBranch rejects.

Related errors


AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01). Data as JSON: /api/errors/07a200cc18c21cc8. Report an issue: GitHub.