d2lang/d2 · error
malformed style setting, expected 2 part path
Error message
malformed style setting, expected 2 part path
What it means
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.
Source
Thrown at d2oracle/edit.go:783
return nil
}
case "label":
if inlined(&arrowhead.Label) {
arrowhead.Label.MapKey.SetScalar(mk.Value.ScalarBox())
return nil
}
case "style":
reservedTargetKey = mk.Key.Path[len(mk.Key.Path)-1].Unbox().ScalarString()
if inlined(attrs.Style.Filled) {
attrs.Style.Filled.MapKey.SetScalar(mk.Value.ScalarBox())
return nil
}
}
}
case "style":
if reservedTargetKey == "" {
if len(mk.Key.Path[reservedIndex:]) != 2 {
return errors.New("malformed style setting, expected 2 part path")
}
reservedTargetKey = mk.Key.Path[reservedIndex+1].Unbox().ScalarString()
}
switch reservedTargetKey {
case "opacity":
if inlined(attrs.Style.Opacity) {
attrs.Style.Opacity.MapKey.SetScalar(mk.Value.ScalarBox())
return nil
}
case "stroke":
if inlined(attrs.Style.Stroke) {
attrs.Style.Stroke.MapKey.SetScalar(mk.Value.ScalarBox())
return nil
}
case "fill":
if inlined(attrs.Style.Fill) {
attrs.Style.Fill.MapKey.SetScalar(mk.Value.ScalarBox())
return nilView on GitHub (pinned to 0d69dca6f5)
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`.
Example fix
// before g, err = d2oracle.Set(g, nil, "(a -> b).style", &opaque) // after g, err = d2oracle.Set(g, nil, "(a -> b).style.opacity", &opaque)
Defensive patterns
Strategy: validation
Validate before calling
mk, err := d2parser.ParseMapKey(key)
if err != nil { return err }
for i, p := range mk.Key.Path {
if p.Unbox().ScalarString() == "style" {
if len(mk.Key.Path)-i != 2 {
return fmt.Errorf("style key %q must be exactly style.<property>", key)
}
}
} Type guard
func styleKeyWellFormed(key string) bool {
mk, err := d2parser.ParseMapKey(key)
if err != nil { return false }
for i, p := range mk.Key.Path {
if p.Unbox().ScalarString() == "style" {
return len(mk.Key.Path)-i == 2
}
}
return true
} Try / catch
err := d2oracle.Set(g, nil, key, &val)
if err != nil && strings.Contains(err.Error(), "malformed style setting, expected 2 part path") {
return fmt.Errorf("use exactly style.<property> in %q", key)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- malformed style setting, expected >= 2 part path
- expected "double-border" to be true or false
- edgeKey must be an edge
- edgeKey must refer to an existing edge
- edge not found
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/a52667aaafbb2ee4.
Report an issue: GitHub.