How to Fix Broken Token References in DESIGN.md: A Complete Guide

Run npx @google/design.md lint DESIGN.md to identify broken references, then verify that every token wrapped in curly braces exists in the YAML front-matter and uses valid dotted-path syntax without circular dependencies.

The google-labs-code/design.md repository defines a Markdown-based specification for design tokens that relies on YAML front-matter for token definitions. When working with these files, you may encounter broken-ref errors that prevent successful linting or export, typically caused by token references that cannot resolve to defined values. Learning how to fix broken token references in DESIGN.md is essential for maintaining valid design systems that compile correctly for downstream consumers.

How the Broken-Ref Rule Works

The linter's broken-ref rule is implemented in packages/cli/src/linter/linter/rules/broken-ref.ts at lines 22-31. This rule scans every component definition in your DESIGN.md file to detect two specific categories of errors:

  1. Unresolved references – Token references in curly braces that point to non-existent tokens in the YAML front-matter
  2. Unknown component sub-tokens – Properties within component definitions that are not recognized as valid sub-tokens

According to the implementation at lines 34-41 of the same file, the rule validates component properties against a VALID_COMPONENT_SUB_TOKENS constant, flagging any unsupported properties as warnings.

Common Causes of Broken References

Token references break for several specific reasons defined in the specification at docs/spec.md (lines 86-88):

  • Reference syntax errors – Tokens must be wrapped in curly braces and use dotted notation (e.g., {colors.primary}) that matches the YAML tree structure exactly
  • Missing token definitions – A reference like {colors.primary-60} fails when primary-60 is not declared in the front-matter colors group
  • Circular dependencies – Token A references Token B, which references Token A, creating an infinite resolution loop
  • Invalid scope – Most token groups require references to point to primitive values, not entire groups, though the components section allows composite references
  • Unsupported component properties – Using property names like borderColor that are not included in the valid sub-tokens list

Step-by-Step Resolution Process

Follow these steps to resolve broken token references in your DESIGN.md files:

  1. Run the linter – Execute npx @google/design.md lint DESIGN.md to generate a report of all broken references with specific component paths

  2. Locate the offending reference – Open the error message to find the full path (e.g., components.button-primary.backgroundColor) and locate the corresponding line in your markdown

  3. Verify token existence – Check the YAML front-matter for the referenced token name. Ensure the group and token exist exactly as spelled in the reference

  4. Correct the syntax – Ensure references follow the exact format {group.token} with no extra spaces, missing braces, or incorrect punctuation as specified in docs/spec.md

  5. Resolve circular references – If token A references token B, ensure token B does not reference token A. Break the cycle by converting one reference to a primitive literal value

  6. Validate component sub-tokens – Remove any properties from component definitions that are not recognized sub-tokens, or rename them to valid alternatives like backgroundColor or textColor

  7. Re-run the linter – Execute the lint command again to confirm all broken-ref errors are resolved

Code Examples

Broken Reference (Missing Token)

This DESIGN.md file references a token that does not exist in the front-matter:

---
colors:
  primary: "#1A1C1E"
components:
  button-primary:
    backgroundColor: "{colors.primary-60}"
---

Running npx @google/design.md lint DESIGN.md produces:


components.button-primary – Reference {colors.primary-60} does not resolve to any defined token.

Fixed Reference

Add the missing token to resolve the error:

---
colors:
  primary: "#1A1C1E"
  primary-60: "#0F0F0F"
components:
  button-primary:
    backgroundColor: "{colors.primary-60}"
---

Circular Reference (Invalid)

This YAML creates an infinite loop:

spacing:
  base: "{spacing.gutter}"
  gutter: "{spacing.base}"

Circular Reference Resolved

Break the cycle with literal values:

spacing:
  base: "16px"
  gutter: "24px"

Invalid Component Sub-Token

This example uses an unsupported property:

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    borderColor: "#ff0000"   # Not a valid sub-token

Fix by removing the invalid property or renaming it to a recognized sub-token defined in the validator.

Summary

  • Broken token references occur when DESIGN.md files contain references to non-existent tokens, circular dependencies, or invalid component sub-tokens
  • The linter at packages/cli/src/linter/linter/rules/broken-ref.ts automatically detects these issues when you run npx @google/design.md lint DESIGN.md
  • Reference syntax must follow {group.token} format exactly as defined in the specification at docs/spec.md
  • Component sub-tokens are restricted to a specific allow-list; unsupported properties trigger warnings
  • Circular references must be broken by converting one side of the cycle to a primitive value

Frequently Asked Questions

What is the exact syntax for token references in DESIGN.md?

Token references must be wrapped in curly braces and use dotted notation that matches the YAML front-matter structure exactly, such as {colors.primary} or {spacing.large}. According to docs/spec.md at line 86, the reference path must correspond to a primitive value in the token group, not the group itself, unless you are working within the special components section which allows composite references.

How do I identify circular references in my design tokens?

Circular references occur when two tokens reference each other directly or through a chain of dependencies that loops back to the start. You can identify them by examining your YAML front-matter for any tokens that use curly-brace references to other tokens that might reference back. The linter will flag these as resolution errors, and you should break the cycle by giving at least one token in the loop a literal primitive value instead of a reference.

What component sub-tokens are considered valid in DESIGN.md?

The components section only accepts specific property names defined in the VALID_COMPONENT_SUB_TOKENS constant within packages/cli/src/linter/linter/rules/broken-ref.ts (lines 34-41). While the exact list depends on the current version of the linter, valid sub-tokens typically include standard properties like backgroundColor and textColor. Properties like borderColor will trigger warnings unless they are explicitly added to the valid tokens list.

How do I run the linter locally to check for broken references?

Navigate to your project directory containing DESIGN.md and run npx @google/design.md lint DESIGN.md. This command, documented in the repository's README.md at lines 313-321, will scan your file and output specific error messages indicating which component paths contain broken references and what the unresolved tokens are.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →