You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GraphQL symbol extraction: fragment X on Y never captured (426 misses on graphql-platform), directive @X never captured, extend only handles extend type #171
The GraphQL pattern set in SymbolExtractor.cs is missing three common SDL / executable-document constructs:
fragment FragmentName on TypeName { ... } — client-side reusable selection sets. The primary building block of Apollo / Relay / urql / graphql-codegen / StrawberryShake / Nitro CLI / any modern GraphQL-over-HTTP client. On ChilliCream/graphql-platform@main (the HotChocolate + StrawberryShake + Nitro mono-repo), 426 real fragment X on Y declarations across 117 files → 0 symbol rows.
directive @directiveName on <LOCATIONS> — SDL directive definitions. The built-in GraphQL spec directives @defer, @oneOf, @specifiedBy plus any custom directives like @auth, @key, @requires, @provides are all invisible. Small scale per file, but 100% coverage miss.
extend interface / extend input / extend enum / extend union / extend schema — the existing pattern only handles extend type X, even though GraphQL allows extending all declarable types.
Same overall shape as the F# / VB / Makefile / SCSS / Rust issues recently filed (#165 / #166 / #167 / #168 / #169) — the per-line regex list is missing real language constructs and the miss is silent.
Repro
curl -fsSL https://raw.githubusercontent.com/Widthdom/CodeIndex/main/install.sh | bash
CDIDX=/root/.local/bin/cdidx
mkdir -p /tmp/srcs &&cd /tmp/srcs
curl -fsSL -o hotchocolate.tar.gz https://codeload.github.com/ChilliCream/graphql-platform/tar.gz/refs/heads/main
tar xzf hotchocolate.tar.gz
# Smaller focused sample first
mkdir -p /tmp/gqltest
cp /tmp/srcs/graphql-platform-main/src/Nitro/CommandLine/src/ChilliCream.Nitro.Client/schema.graphql /tmp/gqltest/
cp /tmp/srcs/graphql-platform-main/src/Nitro/CommandLine/src/ChilliCream.Nitro.Client/fragments.graphql /tmp/gqltest/
cp /tmp/srcs/graphql-platform-main/src/Nitro/CommandLine/src/ChilliCream.Nitro.Client/Apis/Operations/ListApiCommand.graphql /tmp/gqltest/
cp /tmp/srcs/graphql-platform-main/src/HotChocolate/Core/test/Types.Tests/__resources__/schema_coordinates.graphql /tmp/gqltest/
"$CDIDX" /tmp/gqltest --db /tmp/gqltest.db --rebuild
"$CDIDX" status --db /tmp/gqltest.db | tail -6
# Kinds:# class 702# interface 48# enum 21# function 1 ← the one `query ListApiCommandQuery(...)` operation; zero fragments, zero directives
1. Fragments: 120 declarations in fragments.graphql → 0 symbols
"$CDIDX" symbols "ProcessingTimeoutError" --db /tmp/gqltest.db --lang graphql --exact
# class ProcessingTimeoutError schema.graphql:3072-3074 ← the type, OK# (the fragment with the same name in fragments.graphql:12 is NOT in the index)
Fragment coverage gap is the largest. Every client-side GraphQL codebase — the entire reason .graphql files exist alongside source code instead of being embedded — stores reusable fragments in separate files. Missing all of them means callers / references / definition on fragment names return nothing. StrawberryShake, Relay, Apollo Client, graphql-codegen templates, Nitro CLI, every .graphql corpus I've seen has significant fragment use.
Directives matter for auth/schema-federation workflows. Apollo Federation's @key, @external, @provides, @requires are user-authored directives. HotChocolate's directives. Without directive extraction, symbols --kind function is incomplete and AI consumers can't discover the schema's directive surface.
extend coverage gap is smaller by volume but bites schema-stitching / federation codebases hard.
Silent. No warning; user sees classes + interfaces + enums + 1 query as their entire symbol surface of a 120-fragment file.
Suggested direction
Three additive patterns + one alternation widening; all one-line fixes.
Add fragment Name on Type pattern. Kind is a judgment call (function or class). function aligns with how query/mutation/subscription are currently kinded; the intent is "executable-document declaration":
extend schema has no name and is better left to the existing schema { ... } capture — or gets a dedicated nameless-capture row if you want it visible.
(Polish) scalar Name already works — scalars can also be declared without a body (scalar DateTime with no { ... }). The existing BodyStyle.Brace for scalar may incorrectly treat the next type's { as the scalar's body. Quick verification on a scalar-heavy schema would be useful. Not strictly part of this bug; noting for the same regex pass.
Expected impact after fix
On /tmp/srcs/graphql-platform-main:
symbols --kind function --lang graphql --count rises from the current "executable operations only" count to include 426+ fragments and every directive @X.
symbols "ProcessingTimeoutError" --lang graphql returns both the schema type and the fragment by the same name.
callers Error --lang graphql (a fragment spread target) starts producing edges from the 75+ fragments that spread ...Error.
src/CodeIndex/Indexer/ReferenceExtractor.cs — verify whether fragment spread ...FragmentName and directive use @directiveName are already captured as references; if not, this is a natural companion patch.
tests/CodeIndex.Tests/SymbolExtractorTests.cs — fixtures for: (a) fragment Foo on Bar { x } captured as function kind, (b) directive @auth(role: String!) on FIELD_DEFINITION captured as function kind, (c) extend enum Episode { NEWHOPE } captured, (d) extend input FooInput { bar: Int } captured, (e) existing type / query / interface / enum patterns still match (no regression).
Same family: per-line regex list missing a common language construct. GraphQL is the smallest surface of the batch; fragment is the one that bites modern codebases the hardest.
Environment
cdidx: v1.10.0 (installed via install.sh).
Corpus: ChilliCream/graphql-platform@main — 426 fragment X on Y declarations across 117 .graphql files, plus hundreds of directive @X on Y lines, all currently dropped.
Platform: linux-x64 container.
Filed from a cloud Claude Code session per CLOUD_BOOTSTRAP_PROMPT.md.
Summary
The GraphQL pattern set in
SymbolExtractor.csis missing three common SDL / executable-document constructs:fragment FragmentName on TypeName { ... }— client-side reusable selection sets. The primary building block of Apollo / Relay / urql / graphql-codegen / StrawberryShake / Nitro CLI / any modern GraphQL-over-HTTP client. On ChilliCream/graphql-platform@main (the HotChocolate + StrawberryShake + Nitro mono-repo), 426 realfragment X on Ydeclarations across 117 files → 0 symbol rows.directive @directiveName on <LOCATIONS>— SDL directive definitions. The built-in GraphQL spec directives@defer,@oneOf,@specifiedByplus any custom directives like@auth,@key,@requires,@providesare all invisible. Small scale per file, but 100% coverage miss.extend interface/extend input/extend enum/extend union/extend schema— the existing pattern only handlesextend type X, even though GraphQL allows extending all declarable types.Same overall shape as the F# / VB / Makefile / SCSS / Rust issues recently filed (#165 / #166 / #167 / #168 / #169) — the per-line regex list is missing real language constructs and the miss is silent.
Repro
1. Fragments: 120 declarations in fragments.graphql → 0 symbols
Source (
fragments.graphql:12):Rough scale via grep across the whole repo (regular-word regex):
None are captured.
2. Directives: 0 symbols
Source (
schema.graphql:4956,schema.graphql:4959,schema.graphql:4962,schema_coordinates.graphql:26):3.
extendbeyondextend typeThe existing regex at
SymbolExtractor.cs:321only matchesextend type X:extend enum Episode,extend input FooInput,extend interface Node,extend union U,extend schema @...all fall through.Root cause
src/CodeIndex/Indexer/SymbolExtractor.cs:315-323:fragmentpattern.directivepattern.extendalternation covers onlytype.Why it matters
.graphqlfiles exist alongside source code instead of being embedded — stores reusable fragments in separate files. Missing all of them meanscallers/references/definitionon fragment names return nothing. StrawberryShake, Relay, Apollo Client, graphql-codegen templates, Nitro CLI, every .graphql corpus I've seen has significant fragment use.@key,@external,@provides,@requiresare user-authored directives. HotChocolate's directives. Withoutdirectiveextraction,symbols --kind functionis incomplete and AI consumers can't discover the schema's directive surface.extendcoverage gap is smaller by volume but bites schema-stitching / federation codebases hard.Suggested direction
Three additive patterns + one alternation widening; all one-line fixes.
Add
fragment Name on Typepattern. Kind is a judgment call (functionorclass).functionaligns with howquery/mutation/subscriptionare currently kinded; the intent is "executable-document declaration":Add
directive @Namepattern. GraphQL directive names start with@; capture without the@:BodyStyle.Noneis correct because directive declarations do not have{ ... }bodies — they end at the firston <LOCATIONS>.Widen the
extendalternation to cover all declarable types:extend schemahas no name and is better left to the existingschema { ... }capture — or gets a dedicated nameless-capture row if you want it visible.(Polish)
scalar Namealready works — scalars can also be declared without a body (scalar DateTimewith no{ ... }). The existingBodyStyle.Braceforscalarmay incorrectly treat the nexttype's{as the scalar's body. Quick verification on a scalar-heavy schema would be useful. Not strictly part of this bug; noting for the same regex pass.Expected impact after fix
On
/tmp/srcs/graphql-platform-main:symbols --kind function --lang graphql --countrises from the current "executable operations only" count to include 426+ fragments and everydirective @X.symbols "ProcessingTimeoutError" --lang graphqlreturns both the schema type and the fragment by the same name.callers Error --lang graphql(a fragment spread target) starts producing edges from the 75+ fragments that spread...Error.Scope
src/CodeIndex/Indexer/SymbolExtractor.cs— add fragment pattern, add directive pattern, widenextendalternation.src/CodeIndex/Indexer/ReferenceExtractor.cs— verify whether fragment spread...FragmentNameand directive use@directiveNameare already captured as references; if not, this is a natural companion patch.tests/CodeIndex.Tests/SymbolExtractorTests.cs— fixtures for: (a)fragment Foo on Bar { x }captured as function kind, (b)directive @auth(role: String!) on FIELD_DEFINITIONcaptured as function kind, (c)extend enum Episode { NEWHOPE }captured, (d)extend input FooInput { bar: Int }captured, (e) existingtype/query/interface/enumpatterns still match (no regression).Related
if/for/while/switchblocks as function definitions #154 — JS/TS keyword false positives (regex-coverage family).import ( ... )blocks leak(as a symbol name, individual imports never captured, and single-line imports swallow trailing comments #155 — Go import block coverage collapse.use function X\Y\Zcaptures "function",require $variablecaptures the whole expression, group-use and aliases are lost #162 — PHP import extraction gaps.else if,case const Class()etc. asfunction if/function Class— negative lookahead missingelse/case/ more #163 — Dart else-if /case const Class()false positives.namespacedropped,module X.Y.Zmiscategorized asclass, andmember this.Foo = ...methods never captured #165 — F# namespace/module/member missing patterns.Namespace Xnever captured, and all class/sub/function regexes require explicit visibility so unmodified declarations silently drop #166 — VB.NET namespace missing + required-visibility coverage.:=/::=variable assignments as targets (and ignores%-pattern rules entirely) #167 — Makefile:=variable false positives +%pattern rules missing.@functiondeclarations never captured, compound/nested selectors miss everything after the first class,@forwardnot recognized as import #168 — SCSS@function/@forward/ compound selectors missing.impl Trait for Structcaptures the trait name as aclass(hundreds of fakeclass Future/class From/class Defaultrows on tokio), andunsafe impl ... for ...is dropped entirely #169 — Rustimpl Trait for Structcaptures trait name +unsafe impldropped..kts(Kotlin Script / Gradle Kotlin DSL) files are silently skipped —LangMaphas.ktbut no.kts, so everybuild.gradle.kts/settings.gradle.ktsis invisible #170 —.kts(Gradle Kotlin DSL) files silently skipped.Same family: per-line regex list missing a common language construct. GraphQL is the smallest surface of the batch;
fragmentis the one that bites modern codebases the hardest.Environment
install.sh).ChilliCream/graphql-platform@main— 426fragment X on Ydeclarations across 117.graphqlfiles, plus hundreds ofdirective @X on Ylines, all currently dropped.CLOUD_BOOTSTRAP_PROMPT.md.