Product
Hot Chocolate
Version
15.., 16..
Link to minimal reproduction
https://github.com/MarkArchitect/BugSample/blob/main/BugSample.zip
Steps to reproduce
- Create a Shared Library with a domain model: public class Book { ... }
- Create an Extension Library with a custom closed connection:
public sealed class BookPageConnection(Page<Book> page, int maxRelativeCursorCount = 5)
: PageConnection<Book>(page, maxRelativeCursorCount)
{
}
- In the Main Web/API project, reference the Extension Library and create a resolver:
[ObjectType<AuthorWithData>]
public static partial class AuthorWithDataNode
{
[UseConnection]
public static async Task<BookPageConnection> BooksV2(
QueryContext<Book> query,
IResolverContext resolverContext)
{
return new BookPageConnection(Page<Book>.Empty, 5);
}
}
- Compile the Main project.
- You get error:
The type or namespace name 'PageEdge' does not exist in the namespace 'Extension.Shared' (are you missing an assembly reference?)
- If BookPageConnection class is in main project it compiles fine
What is expected?
The Source Generator should inspect the semantic model/type symbols correctly regardless of assembly boundaries. Instead of manual string assembly, it should construct the fully qualified generic name using ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).
The expected output inside the .Type<...>() descriptor method should be:
.Type<global::HotChocolate.Types.ListType<global::HotChocolate.Types.NonNullType<global::HotChocolate.Types.Pagination.PageEdge<global::Lib.Shared.Book>>>>()
Or it should point directly to the generated GraphQL type wrapper:
.Type<global::HotChocolate.Types.ListType<global::HotChocolate.Types.NonNullType<global::Extension.Shared.BookPageEdgeType>>>()
What is actually happening?
The Source Generator successfully creates BookPageEdgeType for PageEdge, but when generating the BookPageConnectionType, it falls back to raw string concatenation.
In ConnectionTypeFileBuilder.cs, the generator relies on connectionType.Namespace and connectionType.EdgeTypeName:
var edgeTypeName = $"{connectionType.Namespace}.{connectionType.EdgeTypeName}";
Because the metadata is read from an external compiled .dll instead of a local syntax tree, connectionType.EdgeTypeName evaluates to a bare string "PageEdge" without its generic type parts.
This produces the following invalid, non-compilable chunk in the generated file:
descriptor
.Field(thisType.GetMember("Edges", global::HotChocolate.Utilities.ReflectionUtils.InstanceMemberFlags)[0])
.Type<global::HotChocolate.Types.ListType<global::HotChocolate.Types.NonNullType<global::Extension.Shared.PageEdge>>>()
The compiler throws a severe error because global::Extension.Shared.PageEdge (or global::HotChocolate.Types.Pagination.PageEdge) is being passed without its generic parameters, breaking C# syntax: "Type PageEdge requires 1 type arguments".
Relevant log output
Severity Code Description Project File Line Suppression State Details
Error (active) CS0234 The type or namespace name 'PageEdge' does not exist in the namespace 'Lib.Shared.Types' (are you missing an assembly reference?) MainProject C:\\BugSample\MainProject\obj\Debug\net8.0\HotChocolate.Types.Analyzers\HotChocolate.Types.Analyzers.GraphQLServerGenerator\BookPageConnectionType.fLGrviozGWgIjRnrCfn0Fg.hc.g.cs 29
Additional context
No response
Product
Hot Chocolate
Version
15.., 16..
Link to minimal reproduction
https://github.com/MarkArchitect/BugSample/blob/main/BugSample.zip
Steps to reproduce
The type or namespace name 'PageEdge' does not exist in the namespace 'Extension.Shared' (are you missing an assembly reference?)
What is expected?
The Source Generator should inspect the semantic model/type symbols correctly regardless of assembly boundaries. Instead of manual string assembly, it should construct the fully qualified generic name using ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).
The expected output inside the .Type<...>() descriptor method should be:
Or it should point directly to the generated GraphQL type wrapper:
What is actually happening?
The Source Generator successfully creates BookPageEdgeType for PageEdge, but when generating the BookPageConnectionType, it falls back to raw string concatenation.
In ConnectionTypeFileBuilder.cs, the generator relies on connectionType.Namespace and connectionType.EdgeTypeName:
Because the metadata is read from an external compiled .dll instead of a local syntax tree, connectionType.EdgeTypeName evaluates to a bare string "PageEdge" without its generic type parts.
This produces the following invalid, non-compilable chunk in the generated file:
The compiler throws a severe error because global::Extension.Shared.PageEdge (or global::HotChocolate.Types.Pagination.PageEdge) is being passed without its generic parameters, breaking C# syntax: "Type PageEdge requires 1 type arguments".
Relevant log output
Additional context
No response