mikefarah/yq · error

cannot encode TOML entry with empty path

Error message

cannot encode TOML entry with empty path

What it means

encodeTopLevelEntry dispatches each root key to attribute/table/array-of-tables writers using the last path element as the key; an empty path means there is no key name to write, so it fails fast with this error. Normally unreachable via normal parsing (root map keys always produce paths), it surfaces via crafted/synthetic nodes or bugs.

Source

Thrown at pkg/yqlib/encoder_toml.go:160

		}
	}

	for i := 0; i < len(node.Content); i += 2 {
		keyNode := node.Content[i]
		valNode := node.Content[i+1]
		if !isTomlAttribute(valNode) {
			if err := te.encodeTopLevelEntry(w, []string{keyNode.Value}, valNode); err != nil {
				return err
			}
		}
	}
	return nil
}

// encodeTopLevelEntry encodes a key/value at the root, dispatching to attribute, table, or array-of-tables
func (te *tomlEncoder) encodeTopLevelEntry(w io.Writer, path []string, node *CandidateNode) error {
	if len(path) == 0 {
		return fmt.Errorf("cannot encode TOML entry with empty path")
	}

	switch node.Kind {
	case ScalarNode:
		// key = value
		return te.writeAttribute(w, path[len(path)-1], node)
	case SequenceNode:
		// Empty arrays should be encoded as [] attributes
		if len(node.Content) == 0 {
			return te.writeArrayAttribute(w, path[len(path)-1], node)
		}

		// If all items are mappings => array of tables; else => array attribute
		allMaps := true
		for _, it := range node.Content {
			if it.Kind != MappingNode {
				allMaps = false
				break

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Find and remove/normalize empty keys: `yq 'with_entries(select(key != ""))'` before `-o toml`.
  2. Rename empty keys: `yq 'with_entries(.key = ((.key | select(. != "")) // "root"))'`.
  3. If calling the library directly, verify the path passed to encodeTopLevelEntry is non-empty.
  4. Preview keys with `yq 'keys' file.yaml` to spot empty-string keys.

Example fix

# before
yq -o toml '.' data.yaml   # data has "": value -> empty path

# after
yq -o toml 'with_entries(.key = ((.key | select(. != "")) // "root"))' data.yaml
Defensive patterns

Strategy: validation

Validate before calling

yq 'keys | any(. == "")' file.yaml   # true means empty keys will break TOML

Type guard

hasEmptyKeys() { [ "$(yq 'keys | any(. == "")' "$1")" = "true" ]; }

Try / catch

yq -o toml '.' file.yaml || yq -o toml 'with_entries(.key = ((.key | select(. != "")) // "root"))' file.yaml

Prevention

When it happens

Trigger: Encoding to `-o toml` a root mapping containing a key node whose path resolves empty — e.g. documents with empty-string keys collapsed by preprocessing, or synthetic nodes built by expressions before encodeRootMapping; called from encodeRootMapping (and reachable in tests like TestTomlEmptyPathPanic).

Common situations: Documents with empty YAML keys (`"": value`); programmatic use of yqlib where a path slice was built incorrectly; expressions that flatten away key names.

Related errors


AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05). Data as JSON: /api/errors/d49e827ebe7f7539. Report an issue: GitHub.