d2lang/d2 · error
failed to parse key %q: %w
Error message
failed to parse key %q: %w
What it means
d2parser.ParseKey parses a single key string (e.g. 'x.y.z') into a d2ast.Key. The parser accumulates issues in a ParseError; if parsing produced any diagnostics, ParseKey wraps them with this error via %w so callers can inspect the underlying parse error.
Source
Thrown at d2parser/parse.go:94
p.err = &ParseError{}
}
m := p.parseMap(true)
if !p.err.Empty() {
return m, p.err
}
return m, nil
}
func ParseKey(key string) (*d2ast.KeyPath, error) {
p := &parser{
reader: strings.NewReader(key),
err: &ParseError{},
}
k := p.parseKey()
if !p.err.Empty() {
return nil, fmt.Errorf("failed to parse key %q: %w", key, p.err)
}
if k == nil {
return nil, fmt.Errorf("empty key: %q", key)
}
return k, nil
}
func ParseMapKey(mapKey string) (*d2ast.Key, error) {
p := &parser{
reader: strings.NewReader(mapKey),
err: &ParseError{},
}
mk := p.parseMapKey()
if !p.err.Empty() {
return nil, fmt.Errorf("failed to parse map key %q: %w", mapKey, p.err)
}
if mk == nil {View on GitHub (pinned to 0d69dca6f5)
Solutions
- Inspect the wrapped parse error (errors.Unwrap) for the exact token/position
- Quote problematic segments, e.g. 'my key' → '"my key"' or use single quotes for IDs with special chars
- Sanitize user-supplied key fragments before composing dotted paths
- Use d2aster to build keys programmatically instead of string concatenation
Example fix
// before
k, err := d2parser.ParseKey("my key.sub") // parse error: space unquoted
// after
k, err := d2parser.ParseKey("'my key'.sub") Defensive patterns
Strategy: try-catch
Validate before calling
func keyLooksValid(k string) bool {
k = strings.TrimSpace(k)
if k == "" { return false }
// disallow obviously unbalanced quotes/brackets
return strings.Count(k, "\"")%2 == 0
} Try / catch
k, err := d2parser.ParseKey(raw)
if err != nil {
if pe := errors.Unwrap(err); pe != nil {
// inspect underlying d2parser.ParseError for position
return fmt.Errorf("invalid key %q: %v", raw, pe)
}
return err
} Prevention
- Quote key segments containing spaces or special characters
- Build keys programmatically with d2aster instead of string concatenation
- Test round-trip: d2fmt.Format the key path before parsing
- Keep d2 library versions consistent across generation and parsing code
When it happens
Trigger: Calling ParseKey with a syntactically invalid key: unbalanced quotes/brackets, invalid characters, malformed connection syntax like 'a -> b' passed to ParseKey when arrows need different handling, or a key containing reserved/illegal sequences.
Common situations: Building keys dynamically from user input or config that contains spaces or special characters without quoting; using key text extracted from another context (comments, IDs); version changes in d2 grammar making previously valid keys invalid.
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
- empty key: %q
- failed to parse map key %q: %w
- empty map key: %q
- failed to parse value %q: %w
- empty value: %q
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/950279f30eb1a389.
Report an issue: GitHub.