d2lang/d2 · error

empty key: %q

Error message

empty key: %q

What it means

ParseKey returns this when parsing succeeded without diagnostics but produced a nil key — meaning the input string was empty or contained nothing that constitutes a key. It signals the caller passed an empty string rather than malformed syntax.

Source

Thrown at d2parser/parse.go:97

	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 {
		return nil, fmt.Errorf("empty map key: %q", mapKey)
	}
	return mk, nil

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Check that the key string is non-empty (after trimming whitespace) before calling ParseKey
  2. Trace where the empty string originates (empty config field, failed split, unset variable)
  3. Skip or default empty keys instead of passing them to the parser

Example fix

// before
k, _ := d2parser.ParseKey(strings.TrimSpace(name)) // name may be ""
// after
name = strings.TrimSpace(name)
if name == "" {
    return fmt.Errorf("cannot resolve empty key")
}
k, err := d2parser.ParseKey(name)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(raw) == "" {
    return nil, fmt.Errorf("refusing to parse empty key")
}
k, err := d2parser.ParseKey(raw)

Try / catch

k, err := d2parser.ParseKey(raw)
if err != nil {
    if strings.HasPrefix(err.Error(), "empty key") {
        // treat as missing input; skip or default
        return nil, nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling d2parser.ParseKey("") or ParseKey with a string containing only whitespace/comments so parseKey returns nil.

Common situations: Config value or loop variable that is empty due to an earlier failed lookup; splitting a path that produced an empty segment; template rendering left the key blank.

Related errors


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