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:
- Unresolved references – Token references in curly braces that point to non-existent tokens in the YAML front-matter
- 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 whenprimary-60is 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
componentssection allows composite references - Unsupported component properties – Using property names like
borderColorthat 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:
-
Run the linter – Execute
npx @google/design.md lint DESIGN.mdto generate a report of all broken references with specific component paths -
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 -
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
-
Correct the syntax – Ensure references follow the exact format
{group.token}with no extra spaces, missing braces, or incorrect punctuation as specified indocs/spec.md -
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
-
Validate component sub-tokens – Remove any properties from component definitions that are not recognized sub-tokens, or rename them to valid alternatives like
backgroundColorortextColor -
Re-run the linter – Execute the lint command again to confirm all
broken-referrors 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.tsautomatically detects these issues when you runnpx @google/design.md lint DESIGN.md - Reference syntax must follow
{group.token}format exactly as defined in the specification atdocs/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →