Summary
Running any .NET unit-test project directly — e.g. dotnet test tests/AGUI.Client.UnitTests — fails to compile locally with a wall of CS0122 '<type>' is inaccessible due to its protection level errors, even on a clean checkout of main. The tests only build when -p:SignAssembly=false is passed, which CI does but a developer running the obvious command does not.
Root cause
sdks/dotnet/Directory.Build.props sets:
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)AGUI.snk</AssemblyOriginatorKeyFile>
Each library exposes internals to its test assembly via, e.g. src/AGUI.Client/AGUI.Client.csproj:
<ItemGroup Condition="'$(SignAssembly)' != 'true'">
<InternalsVisibleTo Include="AGUI.Client.UnitTests" />
<InternalsVisibleTo Include="AGUI.Hosting.AspNetCore.IntegrationTests" />
</ItemGroup>
Because the InternalsVisibleTo items are gated on '$(SignAssembly)' != 'true', a default local build (where SignAssembly=true) generates no InternalsVisibleTo attribute at all — so the test projects, which reference many internal types (ToolCallBuilder, TextMessageBuilder, AGUIHttpTransport, EventStreamConverter, …), fail to compile.
How CI avoids it
.github/workflows/unit-dotnet-sdk.yml runs every test project with -p:SignAssembly=false:
dotnet test tests/AGUI.Client.UnitTests -c Release -p:SignAssembly=false
So CI is green — this is purely a local-developer papercut. The failure mode (dozens of CS0122 errors) gives no hint that the fix is a build flag.
Impact
dotnet test tests/<Project> — the natural command — fails on a clean tree.
- The CS0122 errors are confusing and point at unrelated test files, not at the signing config.
- New contributors (and coding agents) waste time diagnosing what looks like a broken checkout.
Suggested fixes (pick one)
- Make
InternalsVisibleTo work under strong-naming by including the public key (the SDK-native <InternalsVisibleTo> item appends $(PublicKey) automatically for signed assemblies — dropping the Condition may be enough), so the flag is never needed; or
- Auto-disable signing for local/dev builds (e.g. only sign in
Release/CI via a Directory.Build.props condition), so the default dotnet test works; or
- If neither is desired, document the
-p:SignAssembly=false requirement prominently in the .NET SDK README / contributing guide.
Environment
- Reproduced on a clean
main checkout, .NET SDK 10.0.100, macOS.
Summary
Running any
.NETunit-test project directly — e.g.dotnet test tests/AGUI.Client.UnitTests— fails to compile locally with a wall ofCS0122 '<type>' is inaccessible due to its protection levelerrors, even on a clean checkout ofmain. The tests only build when-p:SignAssembly=falseis passed, which CI does but a developer running the obvious command does not.Root cause
sdks/dotnet/Directory.Build.propssets:Each library exposes internals to its test assembly via, e.g.
src/AGUI.Client/AGUI.Client.csproj:Because the
InternalsVisibleToitems are gated on'$(SignAssembly)' != 'true', a default local build (whereSignAssembly=true) generates noInternalsVisibleToattribute at all — so the test projects, which reference manyinternaltypes (ToolCallBuilder,TextMessageBuilder,AGUIHttpTransport,EventStreamConverter, …), fail to compile.How CI avoids it
.github/workflows/unit-dotnet-sdk.ymlruns every test project with-p:SignAssembly=false:So CI is green — this is purely a local-developer papercut. The failure mode (dozens of CS0122 errors) gives no hint that the fix is a build flag.
Impact
dotnet test tests/<Project>— the natural command — fails on a clean tree.Suggested fixes (pick one)
InternalsVisibleTowork under strong-naming by including the public key (the SDK-native<InternalsVisibleTo>item appends$(PublicKey)automatically for signed assemblies — dropping theConditionmay be enough), so the flag is never needed; orRelease/CI via aDirectory.Build.propscondition), so the defaultdotnet testworks; or-p:SignAssembly=falserequirement prominently in the .NET SDK README / contributing guide.Environment
maincheckout, .NET SDK10.0.100, macOS.