d2lang/d2 · error

board names cannot contain dots or quotes

Error message

board names cannot contain dots or quotes

What it means

When the key targets a board (first path element is layers/scenarios/steps), _set validates the board name (second path element). D2 boards are referenced by path in tooling, so dots would be ambiguous with nesting and quotes break naming; a board name containing '.' or '"' is rejected with this error.

Source

Thrown at d2oracle/edit.go:428

				// If we find a deeper obj.Map we need to skip this key too.
				toSkip++
				continue
			}

			scope = maybeNewScope
			mk.Key.Path = mk.Key.Path[toSkip:]
			toSkip = 1
			if len(mk.Key.Path) == 0 {
				mk.Key = nil
			}
		}

		if mk.Key != nil && len(mk.Key.Path) == 2 {
			boardType := mk.Key.Path[0].Unbox().ScalarString()
			if boardType == "layers" || boardType == "scenarios" || boardType == "steps" {
				boardName := mk.Key.Path[1].Unbox().ScalarString()
				if strings.ContainsAny(boardName, ".\"") {
					return fmt.Errorf("board names cannot contain dots or quotes")
				}
				// Force map structure
				var containerMap *d2ast.Map
				for _, n := range scope.Nodes {
					if n.MapKey != nil && n.MapKey.Key != nil && len(n.MapKey.Key.Path) == 1 &&
						n.MapKey.Key.Path[0].Unbox().ScalarString() == boardType {
						containerMap = n.MapKey.Value.Map
						break
					}
				}

				if containerMap == nil {
					containerMap = &d2ast.Map{
						Range: d2ast.MakeRange(",1:0:0-1:0:0"),
					}
					containerMK := &d2ast.Key{
						Key: &d2ast.KeyPath{
							Path: []*d2ast.StringBox{

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Rename the board to remove dots/quotes (use hyphens or underscores instead).
  2. Sanitize generated board names before building the key: replace '.' and '"' characters.
  3. Target the field within the board with a key that only uses the sanitized board name.

Example fix

// before
key := "layers.app.config.db.host" // board name "app" has dot
// after
key := "layers_app_config.db.host" // or rename boards to avoid dots
Defensive patterns

Strategy: validation

Validate before calling

func validBoardName(name string) bool {
    return !strings.ContainsAny(name, ".\"")
}
// before building key: if !validBoardName(boardName) { reject }

Type guard

func safeBoardKey(boardType, boardName, rest string) (string, bool) {
    if strings.ContainsAny(boardName, ".\"") { return "", false }
    return boardType + "." + boardName + rest, true
}

Try / catch

g2, err := d2oracle.Set(g, boardPath, key, tag, value)
if err != nil && strings.Contains(err.Error(), "board names cannot contain dots or quotes") {
    return fmt.Errorf("sanitize board name in key %q", key)
}

Prevention

When it happens

Trigger: Calling Set or Create with a key like `layers.my.board` or `layers."x".field` — any board name segment under layers/scenarios/steps containing a dot or double quote.

Common situations: Using dotted names borrowed from file paths or domain names for layers; programmatic key construction that interpolates un-sanitized names containing dots.

Related errors


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