d2lang/d2 · error

spaces are not allowed in blockstring tags

Error message

spaces are not allowed in blockstring tags

What it means

In _set, when a blockstring tag is provided (tag != nil), it must not contain whitespace because tags become part of the blockstring delimiter (e.g. |`tag ... tag`|). Set rejects a tag containing any space with this error before parsing the key.

Source

Thrown at d2oracle/edit.go:330

	return pathFromScopeKey(g, key, scopeak)
}

func recompile(g *d2graph.Graph) (*d2graph.Graph, error) {
	s := d2format.Format(g.AST)
	g2, _, err := d2compiler.Compile(g.AST.Range.Path, strings.NewReader(s), &d2compiler.CompileOptions{
		FS: g.FS,
	})
	if err != nil {
		return nil, fmt.Errorf("failed to recompile:\n%s\n%w", s, err)
	}
	return g2, nil
}

// TODO merge flat styles
func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) error {
	if tag != nil {
		if hasSpace(*tag) {
			return fmt.Errorf("spaces are not allowed in blockstring tags")
		}
	}

	mk, err := d2parser.ParseMapKey(key)
	if err != nil {
		return err
	}

	if len(mk.Edges) > 1 {
		return errors.New("can only set one edge at a time")
	}

	if value != nil {
		mk.Value = d2ast.MakeValueBox(d2ast.RawString(*value, false))
	} else {
		mk.Value = d2ast.ValueBox{}
	}
	if tag != nil && value != nil {

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Strip or replace whitespace in the tag before calling Set (e.g. camelCase, kebab-case, or underscore).
  2. Pass tag = nil if no blockstring tag is needed.
  3. Validate the tag with strings.ContainsFunc(tag, unicode.IsSpace) before the call.

Example fix

// before
tag := "sql query"
g2, err := d2oracle.Set(g, nil, "desc", &tag, &val) // error
// after
tag := "sql-query"
g2, err := d2oracle.Set(g, nil, "desc", &tag, &val)
Defensive patterns

Strategy: validation

Validate before calling

func validTag(tag *string) bool {
    return tag == nil || !strings.ContainsFunc(*tag, unicode.IsSpace)
}

Type guard

func sanitizeTag(tag string) string {
    return strings.Join(strings.Fields(tag), "-")
}

Try / catch

if err := d2oracle.Set(g, boardPath, key, &tag, &value); err != nil &&
    strings.Contains(err.Error(), "spaces are not allowed in blockstring tags") {
    t := sanitizeTag(tag)
    g2, err = d2oracle.Set(g, boardPath, key, &t, &value)
}

Prevention

When it happens

Trigger: Calling Set(g, boardPath, key, tag, value) where *tag contains a space character, as detected by hasSpace — e.g. tag := ptr("my tag").

Common situations: Building blockstring tags from user input or labels with spaces; forgetting that D2 blockstring tags must be a single token.

Related errors


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