How to Fix Broken Token References with the broken-ref Lint Rule in Design MD

The broken-ref lint rule detects unresolved token references and unknown component sub-tokens in Design System Specifications, reporting errors for missing tokens and warnings for unsupported property names.

The broken-ref rule is a core validator in the Design MD CLI linter that ensures your Design System Specification remains internally consistent. As implemented in the google-labs-code/design.md repository, this rule scans component definitions to verify that every token reference points to a defined token and that every property uses supported sub-token names.

What the broken-ref Rule Checks

The rule implementation in packages/cli/src/linter/linter/rules/broken-ref.ts performs two distinct validation passes over the DesignSystemState.

Unresolved Token References

The rule iterates through every component's unresolvedRefs array to catch references that cannot be resolved to a defined token. At lines 22–31, the code walks each component and creates an error finding for any ref value that does not point to an entry in the tokens section of the spec.

Unknown Component Sub-Tokens

The rule validates property names against the VALID_COMPONENT_SUB_TOKENS constant defined in packages/cli/src/linter/model/spec.ts. At lines 34–42, the code checks each [propName] in comp.properties. If the property name is not listed in the allowed sub-tokens, the rule adds a warning (not an error) to the report.

How to Fix Broken Token References

Follow this workflow to resolve issues flagged by the broken-ref rule.

1. Locate the Offending Component

The linter output includes the full component path (e.g., components.Button). Note the specific reference path that "does not resolve" or the property name flagged as unrecognized.

2. Verify Token Existence

Open your Design System Specification file and check the tokens section. Confirm whether the token referenced in the component's ref field actually exists.

3. Correct or Add the Missing Token

  • If the token is misspelled, update the ref value in the component definition to match the exact token name.
  • If the token is missing, define it under tokens.<tokenName> with the appropriate value structure.

4. Resolve Unknown Sub-Token Warnings

For warnings about property names not in VALID_COMPONENT_SUB_TOKENS:

  • Rename the property to one of the standard allowed tokens (such as background, color, or border).
  • Extend the whitelist only if you control the specification and need a custom sub-token. Modify VALID_COMPONENT_SUB_TOKENS in packages/cli/src/linter/model/spec.ts.

5. Re-run the Linter

After editing the spec file, execute the lint command to verify the fixes:

design-md lint <your-spec>.md

Code Examples: Before and After

Fixing an Unresolved Token Reference

Before (broken):

components:
  Button:
    ref: tokens.buttonPrimary   # Token does not exist

    background: primary

Linter output:


error: components.Button – Reference tokens.buttonPrimary does not resolve to any defined token.

After (fixed):

tokens:
  buttonPrimary:
    background: '#ff5722'
    color: '#ffffff'

components:
  Button:
    ref: tokens.buttonPrimary
    background: primary

Fixing an Unknown Sub-Token

Before (warning):

components:
  Card:
    background: surface
    shadow: medium   # 'shadow' is not in VALID_COMPONENT_SUB_TOKENS

Linter output:


warning: components.Card.shadow – 'shadow' is not a recognized component sub-token.

After (fixed):

components:
  Card:
    background: surface
    elevation: medium   # 'elevation' is a valid sub-token

Summary

  • The broken-ref rule is defined in packages/cli/src/linter/linter/rules/broken-ref.ts with a default severity of error.
  • It validates two issues: unresolved token references (errors) and unknown component sub-tokens (warnings).
  • Fix unresolved refs by ensuring the target token exists in the tokens section or correcting the reference path.
  • Fix sub-token warnings by renaming properties to match VALID_COMPONENT_SUB_TOKENS or extending the whitelist in packages/cli/src/linter/model/spec.ts.
  • The rule metadata is exported as brokenRefRule following the RuleDescriptor interface consumed by the linter engine in packages/cli/src/linter/lint.ts.

Frequently Asked Questions

What severity level does the broken-ref rule use for different issues?

The rule reports errors for unresolved token references and warnings for unknown component sub-tokens. This distinction is configured in the RuleDescriptor exported at lines 47–52 of packages/cli/src/linter/linter/rules/broken-ref.ts, where the default severity is set to 'error' for the rule itself, while sub-token checks explicitly emit warnings.

Where is the list of valid component sub-tokens defined?

The VALID_COMPONENT_SUB_TOKENS constant is defined in packages/cli/src/linter/model/spec.ts. This file establishes the canonical list of property names that components are allowed to use without triggering a warning from the broken-ref rule.

Can I add custom sub-tokens to the valid list?

Yes, but only if you maintain control over the specification codebase. To add custom sub-tokens, modify the VALID_COMPONENT_SUB_TOKENS array in packages/cli/src/linter/model/spec.ts. After changing the source code, rebuild the CLI to apply the new validation rules to your Design System Specifications.

How does the linter identify which references are broken?

The linter builds a DesignSystemState object (prepared in packages/cli/src/linter/spec-config.ts) that tracks every component's unresolvedRefs array. The broken-ref rule simply iterates this array at lines 22–31 of its implementation file, creating a finding for each entry that remains unresolved after the spec is fully parsed.

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 →