Found while analysing the render round-trip corpus in specs-testing (workspace workspaces/eg, a 69-component the component library).
Symptom
Some components that exist in Figma as their own COMPONENT_SET are never captured as subcomponents in the owning component's spec. They then surface as instanceOf references that match nothing, so specs analyze dependencies flags them external: true and the render path skips them (see #276 for the skip behaviour itself).
Concrete case in workspaces/eg:
workspaces/eg/specs/WebHeaderExperimental/examples.yaml references instanceOf: WebHeaderAction
- The Figma file contains a real
COMPONENT_SET named Web Header / Action
WebHeaderExperimental/api.yaml has no subcomponents entry for it
- Result:
WebHeaderAction is reported as an external node with no spec, when the component is in fact part of the analysed library
Why this looks like a matching gap
The workspace config (workspaces/eg/specs.config.yaml) sets:
processing:
subcomponents:
match:
- "{C} / {S}"
- "{C} / _ / {S}"
exclude:
- "{C} / Examples / {S}"
Web Header / Action should match "{C} / {S}" against parent title Web Header (Experimental). It does not — most likely because the parent's Figma title carries the (Experimental) suffix and trailing whitespace ('Web Header (Experimental) '), so {C} never matches. That is a hypothesis, not a verified cause; the first task is to confirm it.
Why it matters
- The dependency graph overstates how much of the library leaves the analysed set.
_analysis/dependencies.graph.yaml reports 28 externals; 16 of those are subcomponents that resolve fine once matched by their formatted title, and this class accounts for part of the remainder.
- Anything keyed off "is this component in the workspace" inherits the error — instance manifest construction, blast-radius reports, and render dependency resolution.
Scope
In the current corpus this is a small class. After matching every external against subcomponent titles, the genuinely unresolvable residue is:
- 6 asset marks / brand logo (
AssetMark*, BrandLogo) — genuinely a different library, correctly external
- 1 glyph (
IconGlyph) — a type: glyph element misclassified as an instance edge, tracked separately
WebHeaderAction — this issue
ButtonEndVisual plus the flattened variant-member names — a different root cause, tracked separately
So this issue is specifically about subcomponents that exist in Figma but never make it into the parent spec's subcomponents block.
Where to look
packages/specs-from-figma/src/ — subcomponent detection and the {C} / {S} pattern matching
workspaces/eg/specs.config.yaml in specs-testing — the config that exercises it
workspaces/eg/specs/_analysis/dependencies.graph.yaml — regenerate with specs analyze dependencies; this file goes stale and a stale copy will give wrong answers
Verification
Web Header / Action appears as a subcomponents entry on WebHeaderExperimental
- It no longer appears as an
external node in dependencies.graph.yaml
- Audit the other components for the same pattern — a title suffix or trailing whitespace defeating
{C} is unlikely to be unique to Web Header
Part of #281.
Found while analysing the render round-trip corpus in
specs-testing(workspaceworkspaces/eg, a 69-component the component library).Symptom
Some components that exist in Figma as their own
COMPONENT_SETare never captured assubcomponentsin the owning component's spec. They then surface asinstanceOfreferences that match nothing, sospecs analyze dependenciesflags themexternal: trueand the render path skips them (see #276 for the skip behaviour itself).Concrete case in
workspaces/eg:workspaces/eg/specs/WebHeaderExperimental/examples.yamlreferencesinstanceOf: WebHeaderActionCOMPONENT_SETnamedWeb Header / ActionWebHeaderExperimental/api.yamlhas nosubcomponentsentry for itWebHeaderActionis reported as an external node with no spec, when the component is in fact part of the analysed libraryWhy this looks like a matching gap
The workspace config (
workspaces/eg/specs.config.yaml) sets:Web Header / Actionshould match"{C} / {S}"against parent titleWeb Header (Experimental). It does not — most likely because the parent's Figma title carries the(Experimental)suffix and trailing whitespace ('Web Header (Experimental) '), so{C}never matches. That is a hypothesis, not a verified cause; the first task is to confirm it.Why it matters
_analysis/dependencies.graph.yamlreports 28 externals; 16 of those are subcomponents that resolve fine once matched by their formatted title, and this class accounts for part of the remainder.Scope
In the current corpus this is a small class. After matching every external against subcomponent titles, the genuinely unresolvable residue is:
AssetMark*,BrandLogo) — genuinely a different library, correctly externalIconGlyph) — atype: glyphelement misclassified as an instance edge, tracked separatelyWebHeaderAction— this issueButtonEndVisualplus the flattened variant-member names — a different root cause, tracked separatelySo this issue is specifically about subcomponents that exist in Figma but never make it into the parent spec's
subcomponentsblock.Where to look
packages/specs-from-figma/src/— subcomponent detection and the{C} / {S}pattern matchingworkspaces/eg/specs.config.yamlinspecs-testing— the config that exercises itworkspaces/eg/specs/_analysis/dependencies.graph.yaml— regenerate withspecs analyze dependencies; this file goes stale and a stale copy will give wrong answersVerification
Web Header / Actionappears as asubcomponentsentry onWebHeaderExperimentalexternalnode independencies.graph.yaml{C}is unlikely to be unique to Web HeaderPart of #281.