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

  1. Inspect the wrapped parse error (errors.Unwrap) for the exact token/position
  2. Quote problematic segments, e.g. 'my key' → '"my key"' or use single quotes for IDs with special chars
  3. Sanitize user-supplied key fragments before composing dotted paths
  4. 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

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

Related errors


AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31). Data as JSON: /api/errors/950279f30eb1a389. Report an issue: GitHub.