Skip to content

fix(agent-installer): pin Newtonsoft ToString overload to avoid GAC binding crash#1833

Merged
Benoît Cortier (CBenoit) merged 1 commit into
masterfrom
fix/newtonsoft-tostring-gac-binding
Jun 23, 2026
Merged

fix(agent-installer): pin Newtonsoft ToString overload to avoid GAC binding crash#1833
Benoît Cortier (CBenoit) merged 1 commit into
masterfrom
fix/newtonsoft-tostring-gac-binding

Conversation

@thenextman

@thenextman Richard Markiewicz (thenextman) commented Jun 23, 2026

Copy link
Copy Markdown
Member

Fixes a failure where installing or reconfiguring the Devolutions Agent could roll back with a MissingMethodException on machines that already have an older Newtonsoft.Json in the Global Assembly Cache (GAC).

The installer's managed (DTF) custom actions formatted agent.json via JObject.ToString(Formatting). That single-argument overload was introduced in Newtonsoft.Json 13.0.4, and the installer references 13.0.4. However, every Newtonsoft.Json 13.x release ships the same AssemblyVersion (13.0.0.0), so the CLR loads whichever 13.x copy is registered in the GAC in preference to the one bundled in the custom-action (SFXCA) payload. When an older 13.x is present in the GAC — commonly installed by Remote Desktop Manager, PowerShell 7, Dell Command, and many other products — the call fails with:

System.MissingMethodException: Method not found:
'System.String Newtonsoft.Json.Linq.JToken.ToString(Newtonsoft.Json.Formatting)'

and the whole MSI transaction rolls back during ConfigureFeatures.

The fix forces the two-argument ToString(Formatting, params JsonConverter[]) overload (by passing an empty converter array) at all three call sites. That overload exists in every 13.x release, so the custom actions now behave correctly no matter which 13.x wins assembly resolution. This required no version change and no change to what ships in the package.

Affected: Agent 2026.2.2 (first build to reference 13.0.4).

The Gateway installer (package/WindowsManaged) was checked as well. It references 13.0.3 and makes no ToString(Formatting) calls, so it is not affected today — though it shares the same structural exposure (strong-named Newtonsoft loaded by DTF custom actions, subject to GAC precedence) and should adopt the same overload discipline if it is ever bumped to 13.0.4+.

Reference: JamesNK/Newtonsoft.Json#3084

Issue: DGW-396

The installer's managed custom actions called JObject.ToString(Formatting),
which binds to a single-argument overload added only in Newtonsoft.Json 13.0.4.
Because every Newtonsoft.Json 13.x release shares AssemblyVersion 13.0.0.0, the
CLR loads whatever 13.x copy is in the GAC ahead of the one bundled in the SFXCA
payload. When an older 13.x is present in the GAC (commonly installed by RDM,
PowerShell 7, Dell Command, and similar products), the call throws
MissingMethodException and the entire installation rolls back.

Forcing the two-argument ToString(Formatting, params JsonConverter[]) overload,
which exists in every 13.x release, makes the custom actions immune to whichever
13.x wins assembly resolution.

Issue: DGW-XXXX
@github-actions

Copy link
Copy Markdown

Let maintainers know that an action is required on their side

  • Add the label release-required Please cut a new release (Devolutions Gateway, Devolutions Agent, Jetsocat, PowerShell module) when you request a maintainer to cut a new release (Devolutions Gateway, Devolutions Agent, Jetsocat, PowerShell module)

  • Add the label release-blocker Follow-up is required before cutting a new release if a follow-up is required before cutting a new release

  • Add the label publish-required Please publish libraries (`Devolutions.Gateway.Utils`, OpenAPI clients, etc) when you request a maintainer to publish libraries (Devolutions.Gateway.Utils, OpenAPI clients, etc.)

  • Add the label publish-blocker Follow-up is required before publishing libraries if a follow-up is required before publishing libraries

@CBenoit Benoît Cortier (CBenoit) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you!

@CBenoit

Copy link
Copy Markdown
Member

I’ll attach a ticket to the squash commit

@CBenoit

Benoît Cortier (CBenoit) commented Jun 23, 2026

Copy link
Copy Markdown
Member

Ticket: DGW-396

@CBenoit Benoît Cortier (CBenoit) enabled auto-merge (squash) June 23, 2026 13:58
@CBenoit Benoît Cortier (CBenoit) changed the title fix(agent): pin Newtonsoft ToString overload to avoid GAC binding crash fix(agent-installer): pin Newtonsoft ToString overload to avoid GAC binding crash Jun 23, 2026
@CBenoit Benoît Cortier (CBenoit) enabled auto-merge (squash) June 23, 2026 13:58
@CBenoit Benoît Cortier (CBenoit) merged commit cd66dd1 into master Jun 23, 2026
44 checks passed
@CBenoit Benoît Cortier (CBenoit) deleted the fix/newtonsoft-tostring-gac-binding branch June 23, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants