{"record":{"id":"4f7892159939356f","repo":"lima-vm/lima","slug":"expected-key-element-got-s","errorCode":null,"errorMessage":"expected <key> element, got <%s>","messagePattern":"expected <key> element, got <(.+?)>","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/plist/plist.go","lineNumber":194,"sourceCode":"\t\t}\n\t}\n}\n\nfunc (d *Dict) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {\n\t*d = make(map[string]Value)\n\n\tfor {\n\t\ttok, err := dec.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\tswitch t := tok.(type) {\n\t\tcase xml.StartElement:\n\t\t\tif t.Name.Local != \"key\" {\n\t\t\t\treturn fmt.Errorf(\"expected <key> element, got <%s>\", t.Name.Local)\n\t\t\t}\n\t\t\tvar key string\n\t\t\tif err := dec.DecodeElement(&key, &t); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tvar vs xml.StartElement\n\t\t\tfor {\n\t\t\t\tvt, err := dec.Token()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif se, ok := vt.(xml.StartElement); ok {\n\t\t\t\t\tvs = se\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar v Value\n\t\t\tif err := dec.DecodeElement(&v, &vs); err != nil {","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/plist/plist.go#L176-L212","documentation":"In a plist <dict>, keys must alternate with values and keys are encoded as <key> elements. Dict.UnmarshalXML (pkg/plist/plist.go:194) requires every start element it reads inside a <dict> to be <key>; anything else (a value element at key position, nesting mistakes, missing value after a key) triggers \"expected <key> element, got <%s>\".","triggerScenarios":"Decoding a plist whose <dict> contains a value element (e.g. <string>) where a <key> is expected — typically because a key/value pair is incomplete, two values were adjacent, or elements were mis-ordered after hand editing.","commonSituations":"Hand-edited plists that dropped a value after a <key>, duplicated keys' values, or placed children out of order; programmatic generators that emit value elements before keys; truncated documents.","solutions":["Ensure every <dict> child sequence is strictly alternating <key>k</key><value/>, <key>k</key><value/> …","Look at the %s tag in the error to find the misplaced element and add or reorder the missing <key>","Validate the plist with plutil -lint (macOS) or xmllint against the plist DTD before parsing","Regenerate the dict programmatically instead of hand-editing to guarantee key/value pairing"],"exampleFix":"// before (fails: value where key expected)\n<dict>\n  <string>value</string>\n  <key>k</key><string>v</string>\n</dict>\n// after\n<dict>\n  <key>name</key><string>value</string>\n  <key>k</key><string>v</string>\n</dict>","handlingStrategy":"validation","validationCode":"func validateDictAlternation(data []byte) error {\n\tdec := xml.NewDecoder(bytes.NewReader(data))\n\tdepth, expectKey := 0, false\n\tfor {\n\t\ttok, err := dec.Token()\n\t\tif err == io.EOF { return nil }\n\t\tif err != nil { return err }\n\t\tse, ok := tok.(xml.StartElement)\n\t\tif !ok { continue }\n\t\tswitch se.Name.Local {\n\t\tcase \"dict\":\n\t\t\tdepth++; expectKey = true\n\t\tcase \"key\":\n\t\t\tif depth > 0 && !expectKey { return errors.New(\"<key> without preceding pair\") }\n\t\t\texpectKey = false\n\t\tdefault:\n\t\t\tif depth > 0 && expectKey { return fmt.Errorf(\"expected <key>, got <%s>\", se.Name.Local) }\n\t\t\texpectKey = true\n\t\t}\n\t}\n}","typeGuard":null,"tryCatchPattern":"var v plist.Value\nif err := xml.Unmarshal(data, &v); err != nil {\n\tif strings.HasPrefix(err.Error(), \"expected <key> element, got <\") {\n\t\ttag := strings.TrimSuffix(strings.TrimPrefix(err.Error(), \"expected <key> element, got <\"), \">\")\n\t\t// locate and fix the misplaced element in the <dict>\n\t}\n\treturn err\n}","preventionTips":["Keep every <dict> as strict key/value alternation; add both halves together when editing","Regenerate dicts programmatically rather than hand-editing XML","Run plutil -lint or xmllint with the plist DTD on inputs before parsing","Never emit two adjacent value elements or leave a <key> without its value"],"tags":["plist","xml","dict","schema"],"backgroundTag":"malformed-plist-dict","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}