{"record":{"id":"e6935f146023af39","repo":"mikefarah/yq","slug":"ini-encoder-supports-only-mappingnode-at-the-root","errorCode":null,"errorMessage":"INI encoder supports only MappingNode at the root level, got %v","messagePattern":"INI encoder supports only MappingNode at the root level, got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/yqlib/encoder_ini.go","lineNumber":94,"sourceCode":"\t\t\t\t// Process nested key-value pairs.\n\t\t\t\tfor j := 0; j < len(valueNode.Content); j += 2 {\n\t\t\t\t\tnestedKeyNode := valueNode.Content[j]\n\t\t\t\t\tnestedValueNode := valueNode.Content[j+1]\n\t\t\t\t\tif nestedValueNode.Kind == ScalarNode {\n\t\t\t\t\t\t_, err := section.NewKey(nestedKeyNode.Value, nestedValueNode.Value)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"Skipping nested non-scalar value for key %s: %v\", nestedKeyNode.Value, nestedValueNode.Kind)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tlog.Debugf(\"Skipping non-scalar value for key %s: %v\", key, valueNode.Kind)\n\t\t\t}\n\t\t}\n\t} else {\n\t\treturn fmt.Errorf(\"INI encoder supports only MappingNode at the root level, got %v\", node.Kind)\n\t}\n\n\t// Use a buffer to store the INI output as the library doesn't support direct io.Writer with indent.\n\tvar buffer bytes.Buffer\n\t_, err := cfg.WriteToIndent(&buffer, ie.indentString)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Write the buffer content to the provided writer.\n\t_, err = writer.Write(buffer.Bytes())\n\treturn err\n}\n\n// writeStringINI is a helper function to write a string to the provided writer for INI encoder.\nfunc writeStringINI(writer io.Writer, content string) error {\n\t_, err := writer.Write([]byte(content))\n\treturn err","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/mikefarah/yq/blob/8b5af0694bb82b41d4ae180fac9972029066f90a/pkg/yqlib/encoder_ini.go#L76-L112","documentation":"The INI encoder can only serialize a top-level MappingNode, because INI files are inherently key/value sections. If the root CandidateNode is a scalar, sequence, or alias, Encode returns this error instead of guessing a representation.","triggerScenarios":"Calling yq with `-o ini` (or Format INI) on input whose evaluated root is not a map — e.g. `yq -o ini '.a' file.yaml` returning a scalar, or a JSON array piped to INI output.","commonSituations":"Converting JSON arrays to INI; piping a scalar expression result to `-o ini`; selecting a nested section then encoding it as the whole document; forgetting that a filter may yield a sequence.","solutions":["Ensure the expression evaluates to a mapping, e.g. wrap results in `{...}`: `yq -o ini '{\"root\": .}'`.","If the value is a sequence, convert it to a map first (e.g. with with_entries or to_entries style transforms) before encoding.","Choose a format that supports arrays/scalars at root (json/yaml) if the data is not map-shaped.","If a selection yields a scalar, drop the filter or re-shape the document before `-o ini`."],"exampleFix":"# before\nyq -o ini '.items' config.yaml   # items is an array -> error\n\n# after\nyq -o ini '{\"items\": {\"count\": (.items | length)}}' config.yaml","handlingStrategy":"validation","validationCode":"kind=$(yq 'kind' file.yaml)\n[ \"$kind\" = \"mapping\" ] || { echo \"INI output requires a map root; got $kind\" >&2; exit 1; }","typeGuard":"isMapRoot() { [ \"$(yq 'kind' \"$1\")\" = \"mapping\" ]; }","tryCatchPattern":"out=$(yq -o ini '.' file.yaml 2>&1) || { echo \"INI encode failed: $out\"; exit 1; }","preventionTips":["Always check `yq 'kind'` on the evaluated result before -o ini","Wrap non-map results in a map with {key: .}","Remember INI has no arrays — reshape sequences first"],"tags":["ini","encoder","yaml","node-kind"],"backgroundTag":"unsupported-root-node-type","analyzedSha":"8b5af0694bb82b41d4ae180fac9972029066f90a","analyzedAt":"2026-09-05T10:57:22.766Z","contentChangedAt":"2026-09-05T10:57:22.766Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}