{"record":{"id":"a52667aaafbb2ee4","repo":"d2lang/d2","slug":"malformed-style-setting-expected-2-part-path-a52667","errorCode":null,"errorMessage":"malformed style setting, expected 2 part path","messagePattern":"malformed style setting, expected 2 part path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2oracle/edit.go","lineNumber":783,"sourceCode":"\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t}\n\t\t\t\t\tcase \"label\":\n\t\t\t\t\t\tif inlined(&arrowhead.Label) {\n\t\t\t\t\t\t\tarrowhead.Label.MapKey.SetScalar(mk.Value.ScalarBox())\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t}\n\t\t\t\t\tcase \"style\":\n\t\t\t\t\t\treservedTargetKey = mk.Key.Path[len(mk.Key.Path)-1].Unbox().ScalarString()\n\t\t\t\t\t\tif inlined(attrs.Style.Filled) {\n\t\t\t\t\t\t\tattrs.Style.Filled.MapKey.SetScalar(mk.Value.ScalarBox())\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase \"style\":\n\t\t\t\tif reservedTargetKey == \"\" {\n\t\t\t\t\tif len(mk.Key.Path[reservedIndex:]) != 2 {\n\t\t\t\t\t\treturn errors.New(\"malformed style setting, expected 2 part path\")\n\t\t\t\t\t}\n\t\t\t\t\treservedTargetKey = mk.Key.Path[reservedIndex+1].Unbox().ScalarString()\n\t\t\t\t}\n\t\t\t\tswitch reservedTargetKey {\n\t\t\t\tcase \"opacity\":\n\t\t\t\t\tif inlined(attrs.Style.Opacity) {\n\t\t\t\t\t\tattrs.Style.Opacity.MapKey.SetScalar(mk.Value.ScalarBox())\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\tcase \"stroke\":\n\t\t\t\t\tif inlined(attrs.Style.Stroke) {\n\t\t\t\t\t\tattrs.Style.Stroke.MapKey.SetScalar(mk.Value.ScalarBox())\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\tcase \"fill\":\n\t\t\t\t\tif inlined(attrs.Style.Fill) {\n\t\t\t\t\t\tattrs.Style.Fill.MapKey.SetScalar(mk.Value.ScalarBox())\n\t\t\t\t\t\treturn nil","sourceCodeStart":765,"sourceCodeEnd":801,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2oracle/edit.go#L765-L801","documentation":"When the reserved part of an edge/attribute key is `style`, the path must contain exactly two parts from the reserved index: `style` plus the style property (e.g. `style.opacity`). A shorter or longer remaining path is malformed for this branch and rejected.","triggerScenarios":"Calling d2oracle.Set/Create with a key like `(a -> b).style` (property missing) or a nested path with extra parts where len(mk.Key.Path[reservedIndex:]) != 2, e.g. `obj.style.opacity.extra` routed to this branch.","commonSituations":"Dropping the property name when composing keys programmatically; appending extra segments (e.g. index or nested key) that leave the wrong path length; copying object-level keys and mangling the style suffix.","solutions":["Use exactly `style.<property>`: `(a -> b).style.opacity`, `.style.stroke`, `.style.fill`, etc.","Remove extra path segments after the property name.","Validate the path length before calling: parse the key and check len(mk.Key.Path) from the reserved index.","For nested arrowhead styles use the dedicated `source-arrowhead`/`target-arrowhead` branches instead of `style`."],"exampleFix":"// before\ng, err = d2oracle.Set(g, nil, \"(a -> b).style\", &opaque)\n// after\ng, err = d2oracle.Set(g, nil, \"(a -> b).style.opacity\", &opaque)","handlingStrategy":"validation","validationCode":"mk, err := d2parser.ParseMapKey(key)\nif err != nil { return err }\nfor i, p := range mk.Key.Path {\n    if p.Unbox().ScalarString() == \"style\" {\n        if len(mk.Key.Path)-i != 2 {\n            return fmt.Errorf(\"style key %q must be exactly style.<property>\", key)\n        }\n    }\n}","typeGuard":"func styleKeyWellFormed(key string) bool {\n    mk, err := d2parser.ParseMapKey(key)\n    if err != nil { return false }\n    for i, p := range mk.Key.Path {\n        if p.Unbox().ScalarString() == \"style\" {\n            return len(mk.Key.Path)-i == 2\n        }\n    }\n    return true\n}","tryCatchPattern":"err := d2oracle.Set(g, nil, key, &val)\nif err != nil && strings.Contains(err.Error(), \"malformed style setting, expected 2 part path\") {\n    return fmt.Errorf(\"use exactly style.<property> in %q\", key)\n}","preventionTips":["Compose style keys from a whitelist of property names (opacity, stroke, fill, ...)","Never append segments after the style property","Never call Set with a bare `.style` suffix","Centralize key construction in one tested helper"],"tags":["edge","style","malformed-key","d2"],"backgroundTag":"malformed-style-path","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}