mikefarah/yq · error

aliases are not supported in TOML

Error message

aliases are not supported in TOML

What it means

The TOML encoder cannot serialize YAML alias nodes (anchors referenced with *). TOML has no concept of anchors/aliases, so when writeArrayAttribute encounters an AliasNode as an array element it fails instead of silently dereferencing. Note that normal yq evaluation usually resolves aliases, so this typically surfaces when aliases reach the encoder unresolved.

Source

Thrown at pkg/yqlib/encoder_toml.go:335

			// Write the element value
			var itemStr string
			switch it.Kind {
			case ScalarNode:
				itemStr = te.formatScalar(it)
			case SequenceNode:
				nested, err := te.sequenceToInlineArray(it)
				if err != nil {
					return err
				}
				itemStr = nested
			case MappingNode:
				inline, err := te.mappingToInlineTable(it)
				if err != nil {
					return err
				}
				itemStr = inline
			case AliasNode:
				return fmt.Errorf("aliases are not supported in TOML")
			default:
				return fmt.Errorf("unsupported array item kind: %v", it.Kind)
			}

			// Always add trailing comma in multiline arrays
			itemStr += ","

			if _, err := w.Write([]byte("  " + itemStr + "\n")); err != nil {
				return err
			}

			// Add blank line between elements (except after the last one)
			if i < len(seq.Content)-1 {
				if _, err := w.Write([]byte("\n")); err != nil {
					return err
				}
			}
		}

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Use evalV3 semantics or ensure aliases are resolved: apply an operator that materializes values, e.g. yq -o toml '(.[] | select(tag == "!!alias"))' is not needed — instead restructure the expression so alias nodes are dereferenced (e.g. pipe through [... (...)] copies).
  2. Explode the anchor manually: replace the alias with its value before encoding (copy the anchored value inline).
  3. If the input format allows, drop anchors/aliases in a pre-pass: yq -o json first (JSON has no aliases so they are dereferenced), then convert to TOML.
  4. Report/patch: handle AliasNode by resolving it.Value in writeArrayAttribute.

Example fix

// before
yq -o toml '.' anchored.yaml   # errors on alias elements
// after
yq -o json '.' anchored.yaml | yq -o toml '.'   # aliases resolved via JSON round-trip
Defensive patterns

Strategy: type-guard

Validate before calling

yq 'any(.[]; tag == "!!alias" or kind == "alias")' in.yaml  # nonzero/skip encode if true

Type guard

// Go (yqlib)
func hasAlias(seq *yqlib.CandidateNode) bool {
    for _, it := range seq.Content {
        if it.Kind == yqlib.AliasNode { return true }
    }
    return false
}

Try / catch

// Go
out, err := yqlib.NewYqFormatter(...).EncodeTOML(node)
if err != nil && strings.Contains(err.Error(), "aliases are not supported in TOML") {
    // dereference aliases (JSON round-trip) and retry
}

Prevention

When it happens

Trigger: Running yq with -o toml (or to_toml) on a document where a sequence element is a YAML alias node (e.g. `a: &x 1\nb: [*x]`) that was not dereferenced during evaluation, hitting the multiline-array branch of writeArrayAttribute.

Common situations: Piping YAML with anchors/merge keys straight to TOML output; building arrays programmatically with alias nodes from load/select on anchored values; scripts converting anchor-heavy YAML config to TOML.

Related errors


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