Troubleshooting
No code is generated after build
Section titled “No code is generated after build”Checklist:
- Verify the manifest file is registered as
AdditionalFilesin.csproj(Mode A) or the domain assembly is referenced withReferenceOutputAssembly="true"(Mode B) - Check the manifest file name ends with
manifest.jsonorPragmaticManifest.json - Verify the manifest has at least one entry in
"endpoints"— empty endpoint arrays produce no output - Check
PragmaticClientBoundariesproperty (if set) matches theoperationIdprefixes in the manifest - Look in
obj/Debug/net10.0/for*.g.csfiles orPragmaticClient.*.Error.g.cserror markers
Build succeeds but generated types are not visible in IDE
Section titled “Build succeeds but generated types are not visible in IDE”Cause: IDE may not have refreshed its analyzer cache.
Fix:
- Restart the IDE or reload the solution
- In Visual Studio: close and reopen the solution, or run
dotnet buildfrom CLI first - In Rider: invalidate caches (File > Invalidate Caches)
- Verify the SG package has
OutputItemType="Analyzer"in the project reference
Error marker file generated instead of client code
Section titled “Error marker file generated instead of client code”If you see a file like PragmaticClient.Showcase_Booking.Error.g.cs containing:
// Client SG error: <message>This means the generator encountered an exception while processing the manifest. Common causes:
- Malformed JSON in the manifest
- Missing required fields (
endpointsarray) - Invalid property types that cause deserialization failures
Fix: Validate the manifest JSON, for example with System.Text.Json:
dotnet script -e "System.Text.Json.JsonDocument.Parse(File.ReadAllText(\"PragmaticManifest.json\"))"Result<object, IError> instead of expected typed response
Section titled “Result<object, IError> instead of expected typed response”Cause: The response type in the manifest is either:
- A generic type like
PagedResult<GuestDto>(generics map toobjectcurrently) - A type not declared in the manifest’s
typesarray - A type with a fully-qualified name that does not match any known CLR type
Fix:
- For entity/DTO types: ensure they appear in the
typesarray with"kind": "entity"or"kind": "dto"and asimpleName - For generic types: this is a known limitation; manual deserialization is needed
PragmaticClientException thrown at runtime
Section titled “PragmaticClientException thrown at runtime”PragmaticClientException is thrown when the HTTP response cannot be interpreted at all (not even as a ProblemDetails error). This typically means:
- The server returned HTML (e.g., a 502 gateway error page)
- The response body is completely empty and not JSON
- Network-level errors that produce non-JSON responses
The generated MapErrorAsync method handles this gracefully by catching JSON parse failures and returning a generic ApiError. A PragmaticClientException should only occur in truly unexpected scenarios outside the normal error mapping flow.
DI registration method not found
Section titled “DI registration method not found”Symptom: AddBookingClient method does not exist.
Checklist:
- Verify the manifest
"assembly"field is set — the boundary name is derived from the last segment (e.g.,"Showcase.Booking"producesAddBookingClient) - Ensure the SG package is correctly referenced as an analyzer
- Check that
Microsoft.Extensions.DependencyInjectionis available (comes transitively from most ASP.NET Core / Blazor templates)
Error types not matching at runtime
Section titled “Error types not matching at runtime”Symptom: result.Error is always ApiError and never a typed error like ConflictError.
Cause: The error code in the ProblemDetails response does not match the errorCode in the manifest.
Debug steps:
- Inspect the raw HTTP response to see the actual ProblemDetails
codevalue - Compare it with the
errorCodevalues in the manifest’stypesarray - The match is case-sensitive and exact —
"CONFLICT"does not match"conflict"
Duplicate DTO names across manifests
Section titled “Duplicate DTO names across manifests”If two manifests define the same simpleName for a type (e.g., both have a GuestDto), the generator processes them independently because each manifest produces code in the same client namespace. This causes CS0101 (duplicate type) compilation errors.
Fix: Use PragmaticClientBoundaries to limit which boundaries are generated, or separate client projects per domain.
Mode B: Domain assembly not providing manifest
Section titled “Mode B: Domain assembly not providing manifest”Checklist:
- The domain assembly must have
[PragmaticMetadata]attributes with category18(Manifest) - This is generated by
Pragmatic.SourceGenerator— ensure the domain project references it - The domain assembly must be referenced with
ReferenceOutputAssembly="true"(default forProjectReference) - Build the domain project first:
dotnet buildthe server project so the metadata attributes are compiled
Generated code has compilation errors
Section titled “Generated code has compilation errors”Common causes and fixes:
| Error | Cause | Fix |
|---|---|---|
CS0246 HttpClient not found | Missing System.Net.Http | Add <FrameworkReference Include="Microsoft.AspNetCore.App" /> or ensure net10.0 target |
CS0246 IServiceCollection not found | Missing DI abstractions | Add Microsoft.Extensions.DependencyInjection.Abstractions package |
CS0246 Result not found | Missing Pragmatic.Result | Add Pragmatic.Result package reference |
CS0246 ApiError not found | Missing Pragmatic.Client | Add Pragmatic.Client package reference |
Manifest versioning
Section titled “Manifest versioning”The manifest uses "$schema": "pragmatic-manifest/v1" to identify its format version. The current generator only supports v1. If the server upgrades its manifest format, ensure the generator package is updated to match.