getsops/sops · error

Error marshaling to json: %s

Error message

Error marshaling to json: %s

What it means

Emitted by the JSON Store's EmitPlainFile when jsonFromTreeBranch fails to marshal the first tree branch to JSON. Since the underlying values come from a decoded tree, this usually means a value in the tree is not representable as a JSON value (e.g. a non-string/non-JSON scalar type set programmatically).

Source

Thrown at stores/json/store.go:362

// EmitEncryptedFile returns the encrypted bytes of the json file corresponding to a
// sops.Tree runtime object
func (store *Store) EmitEncryptedFile(in sops.Tree) ([]byte, error) {
	branches, err := stores.SerializeMetadata(in, stores.MetadataOpts{
		Flatten: stores.MetadataFlattenNone,
	})
	if err != nil {
		return nil, fmt.Errorf("Error marshaling metadata: %s", err)
	}
	return store.EmitPlainFile(branches)
}

// EmitPlainFile returns the plaintext bytes of the json file corresponding to a
// sops.TreeBranches runtime object
func (store *Store) EmitPlainFile(in sops.TreeBranches) ([]byte, error) {
	out, err := store.jsonFromTreeBranch(in[0])
	if err != nil {
		return nil, fmt.Errorf("Error marshaling to json: %s", err)
	}
	out = append(out, '\n')
	return out, nil
}

// EmitValue returns bytes corresponding to a single encoded value
// in a generic interface{} object
func (store *Store) EmitValue(v interface{}) ([]byte, error) {
	s, err := store.encodeValue(v)
	if err != nil {
		return nil, err
	}
	return store.reindentJSON(s)
}

// EmitExample returns the bytes corresponding to an example complex tree
func (store *Store) EmitExample() []byte {
	bytes, err := store.EmitPlainFile(stores.ExampleComplexTree.Branches)

View on GitHub (pinned to 13442bb981)

Solutions

  1. Ensure the tree contains at least one branch whose items all have string keys and JSON-representable values (string, number, bool, nil, nested TreeBranch/slices)
  2. Inspect the wrapped error to find the offending key/type
  3. Normalize unusual value types to strings before emitting
  4. Use the store matching your data type (binary store for opaque data, yaml store for YAML output)

Example fix

// before
branch := sops.TreeBranch{{Key: 123, Value: "x"}} // non-string key
out, err := store.EmitPlainFile(sops.TreeBranches{branch}) // "Error marshaling to json"
// after
branch := sops.TreeBranch{{Key: "123", Value: "x"}}
out, err := store.EmitPlainFile(sops.TreeBranches{branch})
Defensive patterns

Strategy: type-guard

Validate before calling

func jsonSafe(branch sops.TreeBranch) error {
	for _, item := range branch {
		if _, ok := item.Key.(string); !ok {
			return fmt.Errorf("non-string key %T", item.Key)
		}
	}
	return nil
}
if len(branches) == 0 {
	return errors.New("need at least one branch")
}
if err := jsonSafe(branches[0]); err != nil { return err }

Type guard

func isStringKey(item sops.TreeItem) bool {
	_, ok := item.Key.(string)
	return ok
}

Try / catch

out, err := store.EmitPlainFile(branches)
if err != nil {
	if strings.HasPrefix(err.Error(), "Error marshaling to json") {
		return fmt.Errorf("tree contains non-JSON-encodable values: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling EmitPlainFile with a TreeBranches whose first branch contains items with keys that are not strings or values that the store's value-conversion cannot handle (e.g. a TreeItem value of an unexpected Go type inserted programmatically). TestEmitBinaryFileWrongBranches/TestEmitBinaryFileWrongDataType exercise exactly this: wrong branch count or wrong data type in the tree.

Common situations: Custom code building a sops.TreeBranch with non-JSON values (nil branch, wrong types), calling EmitPlainFile on an empty TreeBranches slice (index [0] would panic before this, but wrong types hit this error), or post-decryption mutations of tree values.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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