{"record":{"id":"ae1e11bdfb33ec7a","repo":"mikefarah/yq","slug":"cannot-use-v-as-attribute-only-scalars-are-suppo","errorCode":null,"errorMessage":"cannot use %v as attribute, only scalars are supported","messagePattern":"cannot use (.+?) as attribute, only scalars are supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/yqlib/encoder_xml.go","lineNumber":276,"sourceCode":"\t\tname != e.prefs.ContentName &&\n\t\tname != e.prefs.DirectiveName &&\n\t\t!strings.HasPrefix(name, e.prefs.ProcInstPrefix)\n}\n\nfunc (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *CandidateNode, start xml.StartElement) error {\n\tlog.Debug(\"its a map\")\n\n\t//first find all the attributes and put them on the start token\n\tfor i := 0; i < len(node.Content); i += 2 {\n\t\tkey := node.Content[i]\n\t\tvalue := node.Content[i+1]\n\n\t\tif e.isAttribute(key.Value) {\n\t\t\tif value.Kind == ScalarNode {\n\t\t\t\tattributeName := strings.Replace(key.Value, e.prefs.AttributePrefix, \"\", 1)\n\t\t\t\tstart.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: attributeName}, Value: value.Value})\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"cannot use %v as attribute, only scalars are supported\", value.Tag)\n\t\t\t}\n\t\t}\n\t}\n\n\terr := e.encodeStart(encoder, node, start)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t//now we encode non attribute tokens\n\tfor i := 0; i < len(node.Content); i += 2 {\n\t\tkey := node.Content[i]\n\t\tvalue := node.Content[i+1]\n\n\t\terr := e.encodeComment(encoder, headAndLineComment(key))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/mikefarah/yq/blob/8b5af0694bb82b41d4ae180fac9972029066f90a/pkg/yqlib/encoder_xml.go#L258-L294","documentation":"XML attributes (keys starting with the attribute prefix, default `+` or `@a`) must be scalar values because XML attributes can only hold text. If a key like `+attr` maps to a map/sequence, encodeMap rejects it with this message naming the offending tag.","triggerScenarios":"Encoding `-o xml` a document such as `root: +attr: {a: 1}` or `+attr: [1,2]` — an attribute-prefixed key whose value is a MappingNode or SequenceNode.","commonSituations":"Round-tripping XML that originally had attributes with complex content; hand-authored YAML where an attribute-prefixed key was given a nested structure; tool-generated docs mixing attribute and content conventions.","solutions":["Make the attribute value a scalar: `+attr: value`.","Move the complex data to a child element (non-attribute key or the content key) instead of an attribute.","Rename the key so it no longer starts with the attribute prefix if it is not meant to be an attribute.","Change --xml-attribute-prefix so ordinary keys are not misinterpreted as attributes."],"exampleFix":"// before\nroot:\n  +attrs: {a: 1}\n// after\nroot:\n  +a: 1\n  content: {a: 1}","handlingStrategy":"validation","validationCode":"yq '.root | to_entries | select(.key | test(\"^\\\\+\")) | any(.value | kind != \"scalar\")' in.yaml","typeGuard":"// Go\nfunc attributesAreScalar(m *yqlib.CandidateNode, prefix string) bool {\n    for i := 0; i < len(m.Content); i += 2 {\n        k, v := m.Content[i].Value, m.Content[i+1]\n        if strings.HasPrefix(k, prefix) && v.Kind != yqlib.ScalarNode { return false }\n    }\n    return true\n}","tryCatchPattern":"// Go\nif err := enc.Encode(w, node); err != nil {\n    if strings.Contains(err.Error(), \"only scalars are supported\") {\n        // restructure attribute into a child element and retry\n    }\n}","preventionTips":["Only assign scalar values to attribute-prefixed keys","Use child elements (or the content key) for structured data","Review XML round-trip output for attributes that became maps"],"tags":["xml","encoder","attributes","type-mismatch"],"backgroundTag":"xml-attribute-not-scalar","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"}