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
{{ message }}
Repository navigation
Renaming a class or enum leaves dangling references inside Optional/Handle/Result wrappers and interface function signatures #222
TryRenameClass and TryRenameEnum (Schema/Models/Schema.Rename.cs) find references through EnumerateMemberTypes() (L168-171) and ExpandType (L173-184). That walk has two gaps:
ExpandType recurses only into Array.ElementType. It never descends into WrapperType.ElementType (Schema/Models/Types/WrapperType.cs:19), which covers Optional<>, Handle<> and Result<>.
EnumerateMemberTypes walks only class members. It never visits interface function return types (SchemaFunction.ReturnType) or parameter types (SchemaParameter.Type).
Failure scenario
A schema has class Foo and:
a member typed Handle<Object(Foo)> or Optional<Object(Foo)>, and
an interface function returning Object(Foo) or taking a Foo parameter.
TryRenameClass(Foo, "Bar") returns true, but those references still say Foo. Validate() then reports dangling references in a schema the rename promised to keep consistent. Generated code refers to a type that no longer exists, and the editor's rename-with-cascade silently breaks the schema. Enum renames fail the same way for wrapped or function-signature enum references.
Schema.Test/SchemaRenameTests.cs covers only direct and Array references, which is why this was not caught.
Suggested fix
Make ExpandType recurse into WrapperType.ElementType, and into any other composite that holds an ElementType.
Include every interface's function ReturnType and each parameter's Type in the enumeration, expanded the same way.
If RepointArrayKeys uses the same walk, check it too.
Acceptance criteria
After renaming a class or enum, Validate() reports no dangling reference for a reference nested in Optional, Handle, Result, or Array<Optional<…>>.
The same holds for a reference in an interface function's return type or parameter type.
Priority: Medium. A rename reports success but leaves the schema invalid, so generated code refers to a type that no longer exists. It only affects wrapped references and interface signatures, but the editor's rename-with-cascade hits it in normal use.
Area / suggested assignment:Schema.Rename.cs type walk (EnumerateMemberTypes, ExpandType), and RepointArrayKeys if it shares the walk
Notes: Consider one shared "every type reference in the schema" enumerator, used by both rename and Validate(). Validate already finds these references, which is how the dangling ones show up. Two separate walks are how this gap appeared.
Activity
matt-edmondson commentedon Sep 29, 2026
Triage
Schema.Rename.cstype walk (EnumerateMemberTypes,ExpandType), andRepointArrayKeysif it shares the walkNotes: Consider one shared "every type reference in the schema" enumerator, used by both rename and
Validate(). Validate already finds these references, which is how the dangling ones show up. Two separate walks are how this gap appeared.Generated by Claude Code
Merge main into the #222 branch
Merge the #222 branch, now up to date with main, into the #284 branch