Skip to content

BeamGenerateSchema analyzer rejects Dictionary subclasses, Promise<Unit>, and JToken in callable methods #4588

@allister-beamable

Description

@allister-beamable

Summary

The Beamable.Microservice.SourceGen Roslyn analyzer rejects three type patterns that are common in production C# microservice code. Chris Hanna noted in a support thread that the analyzer may have become "too overzealous with validations."

Affected patterns

All three were confirmed with a bats integration test suite (dotnet build on a real microservice project, CLI 7.0.1).

1. Dictionary subclass as callable return type

public class MyMap : Dictionary<string, string> { }

[ClientCallable]
public async Task<MyMap> GetMap() { ... }

Error: BEAM_SRV_0021 — the analyzer flags the Object base type of Dictionary<> as non-serializable.

2. Promise<Unit> callable return type

[ClientCallable]
public Promise<Unit> DoWork() { ... }

Error: BEAM_SRV_0012Unit is not decorated with [Serializable], so the analyzer rejects it.

3. JToken field in a callable return type

[Serializable]
public class Response { public JToken Payload; }

[ClientCallable]
public async Task<Response> GetData() { ... }

Error: BEAM_SRV_0012JToken (Newtonsoft.Json) is not [Serializable], so the analyzer rejects the containing class.

Workaround

Comment out or remove the Beamable.Microservice.SourceGen <PackageReference> in the affected service's .csproj. The build succeeds and the service functions normally without the analyzer present.

Additional note

IsCallableAttribute() in ServicesAnalyzer.cs (around line 1047) walks only one level of inheritance when checking whether an attribute is callable. This means [AdminOnlyCallable] (AdminOnlyCallable : ClientCallable : CallableAttribute — two levels deep) is silently skipped by the analyzer. Methods decorated with [AdminOnlyCallable] do not trigger any BEAM_SRV validation, even for types that would fail under [ClientCallable]. This may be intentional (admin-only callables have fewer serialization requirements at runtime) but it is worth confirming. (See #4591)

Expected behavior

  • Dictionary subclasses, Promise<Unit>, and JToken fields should either be explicitly allowed or produce a clear error message that explains why they are rejected and what the recommended replacement pattern is.
  • The inheritance-walk depth of IsCallableAttribute() should be documented or deepened to match actual callable attribute hierarchy.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions