Skip to content

[HotReloadAgent] fix possible NullReferenceException#52367

Merged
jonathanpeppers merged 4 commits intorelease/10.0.2xxfrom
dev/peppers/HotReloadAgentNRE
Jan 10, 2026
Merged

[HotReloadAgent] fix possible NullReferenceException#52367
jonathanpeppers merged 4 commits intorelease/10.0.2xxfrom
dev/peppers/HotReloadAgentNRE

Conversation

@jonathanpeppers
Copy link
Member

When running on a platform like Android, startup hooks can run via .NET's runtimeconfig.json, such as:

<ItemGroup>
  <RuntimeHostConfigurationOption Include="STARTUP_HOOKS" Value="Microsoft.Extensions.DotNetDeltaApplier" />
</ItemGroup>

If done this way, $DOTNET_STARTUP_HOOKS can be null, leading to:

01-08 16:07:49.336 14598 14598 F mono-rt :  System.NullReferenceException: Object reference not set to an instance of an object.
01-08 16:07:49.336 14598 14598 F mono-rt :    at Microsoft.DotNet.HotReload.HotReloadAgent.RemoveCurrentAssembly(Type startupHookType, String environment)
01-08 16:07:49.336 14598 14598 F mono-rt :    at Microsoft.DotNet.HotReload.HotReloadAgent.ClearHotReloadEnvironmentVariables(Type startupHookType)
01-08 16:07:49.336 14598 14598 F mono-rt :    at StartupHook.Initialize()
01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
01-08 16:07:49.336 14598 14598 F mono-rt :    --- End of inner exception stack trace ---
01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
01-08 16:07:49.336 14598 14598 F mono-rt :    at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
01-08 16:07:49.336 14598 14598 F mono-rt :    at System.StartupHookProvider.ProcessStartupHooks(String diagnosticStartupHooks)

I think we should remove the ! and do a better null check, to just prevent this from happening.

I don't know yet if we'll use the env var or the runtimeconfig.json by default, but this seems reasonable to fix.

With the fix, it makes it to an expected state:

01-08 16:20:20.560 17468 17468 I DOTNET  : [HotReload] Environment variable DOTNET_WATCH_HOTRELOAD_NAMEDPIPE_NAME has no value

When running on a platform like Android, startup hooks can run via
.NET's `runtimeconfig.json`, such as:

    <ItemGroup>
      <RuntimeHostConfigurationOption Include="STARTUP_HOOKS" Value="Microsoft.Extensions.DotNetDeltaApplier" />
    </ItemGroup>

If done this way, `$DOTNET_STARTUP_HOOKS` can be `null`, leading to:

    01-08 16:07:49.336 14598 14598 F mono-rt :  System.NullReferenceException: Object reference not set to an instance of an object.
    01-08 16:07:49.336 14598 14598 F mono-rt :    at Microsoft.DotNet.HotReload.HotReloadAgent.RemoveCurrentAssembly(Type startupHookType, String environment)
    01-08 16:07:49.336 14598 14598 F mono-rt :    at Microsoft.DotNet.HotReload.HotReloadAgent.ClearHotReloadEnvironmentVariables(Type startupHookType)
    01-08 16:07:49.336 14598 14598 F mono-rt :    at StartupHook.Initialize()
    01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
    01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
    01-08 16:07:49.336 14598 14598 F mono-rt :    --- End of inner exception stack trace ---
    01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
    01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
    01-08 16:07:49.336 14598 14598 F mono-rt :    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
    01-08 16:07:49.336 14598 14598 F mono-rt :    at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
    01-08 16:07:49.336 14598 14598 F mono-rt :    at System.StartupHookProvider.ProcessStartupHooks(String diagnosticStartupHooks)

I think we should remove the `!` and do a better null check, to just
prevent this from happening.

I don't know yet if we'll use the env var or the `runtimeconfig.json`
by default, but this seems reasonable to fix.

With the fix, it makes it to an expected state:

    01-08 16:20:20.560 17468 17468 I DOTNET  : [HotReload] Environment variable DOTNET_WATCH_HOTRELOAD_NAMEDPIPE_NAME has no value
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a NullReferenceException in the HotReloadAgent that occurs on platforms like Android where startup hooks can be configured via runtimeconfig.json instead of environment variables, resulting in a null DOTNET_STARTUP_HOOKS variable.

Key changes:

  • Remove null-forgiving operator when retrieving environment variable
  • Update RemoveCurrentAssembly to accept nullable string parameter
  • Use string.IsNullOrEmpty() for more robust null/empty checking

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants