diff --git a/project-words b/project-words
index 08a823b8e..d0107c4b5 100644
--- a/project-words
+++ b/project-words
@@ -26,6 +26,7 @@ dont
 eglot
 Eglot
 eruby
+EUTF
 exitstatus
 EXTGLOB
 fakehome
diff --git a/vscode/activation.rb b/vscode/activation.rb
index 8c0eec78e..4d903365f 100644
--- a/vscode/activation.rb
+++ b/vscode/activation.rb
@@ -1,2 +1,3 @@
-env = { env: ENV.to_h, yjit: !!defined?(RubyVM::YJIT), version: RUBY_VERSION, gemPath: Gem.path }.to_json
-STDERR.print("RUBY_LSP_ACTIVATION_SEPARATOR#{env}RUBY_LSP_ACTIVATION_SEPARATOR")
+env = ENV.map { |k, v| "#{k}RUBY_LSP_VS#{v}" }
+env.unshift(RUBY_VERSION, Gem.path.join(","), !!defined?(RubyVM::YJIT))
+STDERR.print("RUBY_LSP_ACTIVATION_SEPARATOR#{env.join("RUBY_LSP_FS")}RUBY_LSP_ACTIVATION_SEPARATOR")
diff --git a/vscode/src/debugger.ts b/vscode/src/debugger.ts
index 88b115174..b4ff8472d 100644
--- a/vscode/src/debugger.ts
+++ b/vscode/src/debugger.ts
@@ -258,9 +258,6 @@ export class Debugger
 
       this.logDebuggerMessage(`Spawning debugger in directory ${cwd}`);
       this.logDebuggerMessage(`   Command bundle ${args.join(" ")}`);
-      this.logDebuggerMessage(
-        `   Environment ${JSON.stringify(configuration.env)}`,
-      );
 
       this.debugProcess = spawn("bundle", args, {
         shell: true,
diff --git a/vscode/src/ruby/chruby.ts b/vscode/src/ruby/chruby.ts
index 9beb5c869..ffebb4088 100644
--- a/vscode/src/ruby/chruby.ts
+++ b/vscode/src/ruby/chruby.ts
@@ -200,7 +200,7 @@ export class Chruby extends VersionManager {
     ].join(";");
 
     const result = await this.runScript(
-      `${rubyExecutableUri.fsPath} -W0 -e '${script}'`,
+      `${rubyExecutableUri.fsPath} -EUTF-8:UTF-8 -e '${script}'`,
     );
 
     const [defaultGems, gemHome, yjit, version] =
diff --git a/vscode/src/ruby/versionManager.ts b/vscode/src/ruby/versionManager.ts
index 484e8133b..07bce453a 100644
--- a/vscode/src/ruby/versionManager.ts
+++ b/vscode/src/ruby/versionManager.ts
@@ -14,7 +14,10 @@ export interface ActivationResult {
   gemPath: string[];
 }
 
+// Changes to either one of these values have to be synchronized with a corresponding update in `activation.rb`
 export const ACTIVATION_SEPARATOR = "RUBY_LSP_ACTIVATION_SEPARATOR";
+export const VALUE_SEPARATOR = "RUBY_LSP_VS";
+export const FIELD_SEPARATOR = "RUBY_LSP_FS";
 
 export abstract class VersionManager {
   protected readonly outputChannel: WorkspaceChannel;
@@ -56,32 +59,33 @@ export abstract class VersionManager {
   // language server
   abstract activate(): Promise<ActivationResult>;
 
-  protected async runEnvActivationScript(activatedRuby: string) {
+  protected async runEnvActivationScript(
+    activatedRuby: string,
+  ): Promise<ActivationResult> {
     const activationUri = vscode.Uri.joinPath(
       this.context.extensionUri,
       "activation.rb",
     );
+
     const result = await this.runScript(
-      `${activatedRuby} -W0 -rjson '${activationUri.fsPath}'`,
+      `${activatedRuby} -EUTF-8:UTF-8 '${activationUri.fsPath}'`,
     );
 
     const activationContent = new RegExp(
-      `${ACTIVATION_SEPARATOR}(.*)${ACTIVATION_SEPARATOR}`,
+      `${ACTIVATION_SEPARATOR}([^]*)${ACTIVATION_SEPARATOR}`,
     ).exec(result.stderr);
 
-    return this.parseWithErrorHandling(activationContent![1]);
-  }
-
-  protected parseWithErrorHandling(json: string) {
-    try {
-      return JSON.parse(json);
-    } catch (error: any) {
-      this.outputChannel.error(
-        `Tried parsing invalid JSON environment: ${json}`,
-      );
-
-      throw error;
-    }
+    const [version, gemPath, yjit, ...envEntries] =
+      activationContent![1].split(FIELD_SEPARATOR);
+
+    return {
+      version,
+      gemPath: gemPath.split(","),
+      yjit: yjit === "true",
+      env: Object.fromEntries(
+        envEntries.map((entry) => entry.split(VALUE_SEPARATOR)),
+      ),
+    };
   }
 
   // Runs the given command in the directory for the Bundle, using the user's preferred shell and inheriting the current
@@ -99,14 +103,12 @@ export abstract class VersionManager {
     this.outputChannel.info(
       `Running command: \`${command}\` in ${this.bundleUri.fsPath} using shell: ${shell}`,
     );
-    this.outputChannel.debug(
-      `Environment used for command: ${JSON.stringify(process.env)}`,
-    );
 
     return asyncExec(command, {
       cwd: this.bundleUri.fsPath,
       shell,
       env: process.env,
+      encoding: "utf-8",
     });
   }
 
diff --git a/vscode/src/test/suite/debugger.test.ts b/vscode/src/test/suite/debugger.test.ts
index c2dc1b146..dc0a7d237 100644
--- a/vscode/src/test/suite/debugger.test.ts
+++ b/vscode/src/test/suite/debugger.test.ts
@@ -198,16 +198,14 @@ suite("Debugger", () => {
       'source "https://rubygems.org"\ngem "debug"',
     );
 
-    const extensionPath = path.dirname(
-      path.dirname(path.dirname(path.dirname(__dirname))),
-    );
+    const extensionPath = path.dirname(path.dirname(path.dirname(__dirname)));
     const context = {
       subscriptions: [],
       workspaceState: {
         get: () => undefined,
         update: () => undefined,
       },
-      extensionUri: vscode.Uri.file(path.join(extensionPath, "vscode")),
+      extensionUri: vscode.Uri.file(extensionPath),
     } as unknown as vscode.ExtensionContext;
     const outputChannel = new WorkspaceChannel("fake", LOG_CHANNEL);
     const workspaceFolder: vscode.WorkspaceFolder = {
diff --git a/vscode/src/test/suite/ruby.test.ts b/vscode/src/test/suite/ruby.test.ts
index 5110f0651..dbe6a8644 100644
--- a/vscode/src/test/suite/ruby.test.ts
+++ b/vscode/src/test/suite/ruby.test.ts
@@ -10,7 +10,11 @@ import { Ruby, ManagerIdentifier } from "../../ruby";
 import { WorkspaceChannel } from "../../workspaceChannel";
 import { LOG_CHANNEL } from "../../common";
 import * as common from "../../common";
-import { ACTIVATION_SEPARATOR } from "../../ruby/versionManager";
+import {
+  ACTIVATION_SEPARATOR,
+  FIELD_SEPARATOR,
+  VALUE_SEPARATOR,
+} from "../../ruby/versionManager";
 
 import { FAKE_TELEMETRY } from "./fakeTelemetry";
 
@@ -125,16 +129,16 @@ suite("Ruby environment activation", () => {
         },
       } as unknown as vscode.WorkspaceConfiguration);
 
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.3.5",
-      gemPath: ["~/.gem/ruby/3.3.5", "/opt/rubies/3.3.5/lib/ruby/gems/3.3.0"],
-    };
+    const envStub = [
+      "3.3.5",
+      "~/.gem/ruby/3.3.5,/opt/rubies/3.3.5/lib/ruby/gems/3.3.0",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const ruby = new Ruby(
diff --git a/vscode/src/test/suite/ruby/asdf.test.ts b/vscode/src/test/suite/ruby/asdf.test.ts
index 9adde6d68..f03649e3d 100644
--- a/vscode/src/test/suite/ruby/asdf.test.ts
+++ b/vscode/src/test/suite/ruby/asdf.test.ts
@@ -8,7 +8,11 @@ import sinon from "sinon";
 import { Asdf } from "../../../ruby/asdf";
 import { WorkspaceChannel } from "../../../workspaceChannel";
 import * as common from "../../../common";
-import { ACTIVATION_SEPARATOR } from "../../../ruby/versionManager";
+import {
+  ACTIVATION_SEPARATOR,
+  FIELD_SEPARATOR,
+  VALUE_SEPARATOR,
+} from "../../../ruby/versionManager";
 
 suite("Asdf", () => {
   if (os.platform() === "win32") {
@@ -41,15 +45,16 @@ suite("Asdf", () => {
       context,
       async () => {},
     );
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const findInstallationStub = sinon
@@ -61,12 +66,13 @@ suite("Asdf", () => {
 
     assert.ok(
       execStub.calledOnceWithExactly(
-        `. ${os.homedir()}/.asdf/asdf.sh && asdf exec ruby -W0 -rjson '/fake/activation.rb'`,
+        `. ${os.homedir()}/.asdf/asdf.sh && asdf exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
         {
           cwd: workspacePath,
           shell: "/bin/bash",
           // eslint-disable-next-line no-process-env
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );
@@ -95,15 +101,16 @@ suite("Asdf", () => {
       context,
       async () => {},
     );
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
 
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const findInstallationStub = sinon
@@ -117,12 +124,13 @@ suite("Asdf", () => {
 
     assert.ok(
       execStub.calledOnceWithExactly(
-        `. ${os.homedir()}/.asdf/asdf.fish && asdf exec ruby -W0 -rjson '/fake/activation.rb'`,
+        `. ${os.homedir()}/.asdf/asdf.fish && asdf exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
         {
           cwd: workspacePath,
           shell: "/opt/homebrew/bin/fish",
           // eslint-disable-next-line no-process-env
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );
diff --git a/vscode/src/test/suite/ruby/custom.test.ts b/vscode/src/test/suite/ruby/custom.test.ts
index 41cb6dbbb..42dadc64f 100644
--- a/vscode/src/test/suite/ruby/custom.test.ts
+++ b/vscode/src/test/suite/ruby/custom.test.ts
@@ -9,7 +9,11 @@ import sinon from "sinon";
 import { Custom } from "../../../ruby/custom";
 import { WorkspaceChannel } from "../../../workspaceChannel";
 import * as common from "../../../common";
-import { ACTIVATION_SEPARATOR } from "../../../ruby/versionManager";
+import {
+  ACTIVATION_SEPARATOR,
+  FIELD_SEPARATOR,
+  VALUE_SEPARATOR,
+} from "../../../ruby/versionManager";
 
 suite("Custom", () => {
   const context = {
@@ -40,15 +44,16 @@ suite("Custom", () => {
       async () => {},
     );
 
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const commandStub = sinon
@@ -65,16 +70,13 @@ suite("Custom", () => {
 
     assert.ok(
       execStub.calledOnceWithExactly(
-<<<<<<< Updated upstream
-        `my_version_manager activate_env && ruby -W0 -rjson '/fake/activation.rb'`,
-=======
-        `my_version_manager activate_env && ruby '${activationUri.fsPath}'`,
->>>>>>> Stashed changes
+        `my_version_manager activate_env && ruby -EUTF-8:UTF-8 '${activationUri.fsPath}'`,
         {
           cwd: uri.fsPath,
           shell,
           // eslint-disable-next-line no-process-env
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );
diff --git a/vscode/src/test/suite/ruby/mise.test.ts b/vscode/src/test/suite/ruby/mise.test.ts
index 6ba906868..7fade58f0 100644
--- a/vscode/src/test/suite/ruby/mise.test.ts
+++ b/vscode/src/test/suite/ruby/mise.test.ts
@@ -9,7 +9,11 @@ import sinon from "sinon";
 import { Mise } from "../../../ruby/mise";
 import { WorkspaceChannel } from "../../../workspaceChannel";
 import * as common from "../../../common";
-import { ACTIVATION_SEPARATOR } from "../../../ruby/versionManager";
+import {
+  ACTIVATION_SEPARATOR,
+  FIELD_SEPARATOR,
+  VALUE_SEPARATOR,
+} from "../../../ruby/versionManager";
 
 suite("Mise", () => {
   if (os.platform() === "win32") {
@@ -44,15 +48,16 @@ suite("Mise", () => {
       async () => {},
     );
 
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
     const findStub = sinon
       .stub(mise, "findMiseUri")
@@ -69,12 +74,13 @@ suite("Mise", () => {
 
     assert.ok(
       execStub.calledOnceWithExactly(
-        `${os.homedir()}/.local/bin/mise x -- ruby -W0 -rjson '/fake/activation.rb'`,
+        `${os.homedir()}/.local/bin/mise x -- ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
         {
           cwd: workspacePath,
           shell: vscode.env.shell,
           // eslint-disable-next-line no-process-env
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );
@@ -104,15 +110,16 @@ suite("Mise", () => {
       async () => {},
     );
 
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const misePath = path.join(workspacePath, "mise");
@@ -133,12 +140,13 @@ suite("Mise", () => {
 
     assert.ok(
       execStub.calledOnceWithExactly(
-        `${misePath} x -- ruby -W0 -rjson '/fake/activation.rb'`,
+        `${misePath} x -- ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
         {
           cwd: workspacePath,
           shell: vscode.env.shell,
           // eslint-disable-next-line no-process-env
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );
diff --git a/vscode/src/test/suite/ruby/none.test.ts b/vscode/src/test/suite/ruby/none.test.ts
index 1aef080b6..f3cbd5aea 100644
--- a/vscode/src/test/suite/ruby/none.test.ts
+++ b/vscode/src/test/suite/ruby/none.test.ts
@@ -9,7 +9,11 @@ import sinon from "sinon";
 import { None } from "../../../ruby/none";
 import { WorkspaceChannel } from "../../../workspaceChannel";
 import * as common from "../../../common";
-import { ACTIVATION_SEPARATOR } from "../../../ruby/versionManager";
+import {
+  ACTIVATION_SEPARATOR,
+  FIELD_SEPARATOR,
+  VALUE_SEPARATOR,
+} from "../../../ruby/versionManager";
 
 suite("None", () => {
   test("Invokes Ruby directly", async () => {
@@ -39,15 +43,16 @@ suite("None", () => {
       async () => {},
     );
 
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const { env, version, yjit } = await none.activate();
@@ -60,16 +65,16 @@ suite("None", () => {
     const shell = os.platform() === "win32" ? undefined : vscode.env.shell;
 
     assert.ok(
-<<<<<<< Updated upstream
-      execStub.calledOnceWithExactly(`ruby -W0 -rjson '/fake/activation.rb'`, {
-=======
-      execStub.calledOnceWithExactly(`ruby '${activationUri.fsPath}'`, {
->>>>>>> Stashed changes
-        cwd: uri.fsPath,
-        shell,
-        // eslint-disable-next-line no-process-env
-        env: process.env,
-      }),
+      execStub.calledOnceWithExactly(
+        `ruby -EUTF-8:UTF-8 '${activationUri.fsPath}'`,
+        {
+          cwd: uri.fsPath,
+          shell,
+          // eslint-disable-next-line no-process-env
+          env: process.env,
+          encoding: "utf-8",
+        },
+      ),
     );
 
     assert.strictEqual(version, "3.0.0");
diff --git a/vscode/src/test/suite/ruby/rbenv.test.ts b/vscode/src/test/suite/ruby/rbenv.test.ts
index d13a4116b..a0d4d30ed 100644
--- a/vscode/src/test/suite/ruby/rbenv.test.ts
+++ b/vscode/src/test/suite/ruby/rbenv.test.ts
@@ -9,7 +9,11 @@ import sinon from "sinon";
 import { Rbenv } from "../../../ruby/rbenv";
 import { WorkspaceChannel } from "../../../workspaceChannel";
 import * as common from "../../../common";
-import { ACTIVATION_SEPARATOR } from "../../../ruby/versionManager";
+import {
+  ACTIVATION_SEPARATOR,
+  FIELD_SEPARATOR,
+  VALUE_SEPARATOR,
+} from "../../../ruby/versionManager";
 
 suite("Rbenv", () => {
   if (os.platform() === "win32") {
@@ -44,27 +48,29 @@ suite("Rbenv", () => {
       async () => {},
     );
 
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const { env, version, yjit } = await rbenv.activate();
 
     assert.ok(
       execStub.calledOnceWithExactly(
-        `rbenv exec ruby -W0 -rjson '/fake/activation.rb'`,
+        `rbenv exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
         {
           cwd: workspacePath,
           shell: vscode.env.shell,
           // eslint-disable-next-line no-process-env
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );
@@ -92,15 +98,16 @@ suite("Rbenv", () => {
       async () => {},
     );
 
-    const envStub = {
-      env: { ANY: "true" },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const rbenvPath = path.join(workspacePath, "rbenv");
@@ -121,12 +128,13 @@ suite("Rbenv", () => {
 
     assert.ok(
       execStub.calledOnceWithExactly(
-        `${rbenvPath} exec ruby -W0 -rjson '/fake/activation.rb'`,
+        `${rbenvPath} exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
         {
           cwd: workspacePath,
           shell: vscode.env.shell,
           // eslint-disable-next-line no-process-env
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );
@@ -139,54 +147,4 @@ suite("Rbenv", () => {
     configStub.restore();
     fs.rmSync(workspacePath, { recursive: true, force: true });
   });
-
-  test("Reports invalid JSON environments", async () => {
-    // eslint-disable-next-line no-process-env
-    const workspacePath = process.env.PWD!;
-    const workspaceFolder = {
-      uri: vscode.Uri.from({ scheme: "file", path: workspacePath }),
-      name: path.basename(workspacePath),
-      index: 0,
-    };
-    const outputChannel = new WorkspaceChannel("fake", common.LOG_CHANNEL);
-    const rbenv = new Rbenv(
-      workspaceFolder,
-      outputChannel,
-      context,
-      async () => {},
-    );
-
-    const execStub = sinon.stub(common, "asyncExec").resolves({
-      stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}not a json${ACTIVATION_SEPARATOR}`,
-    });
-
-    const errorStub = sinon.stub(outputChannel, "error");
-
-    await assert.rejects(
-      rbenv.activate(),
-      "SyntaxError: Unexpected token 'o', \"not a json\" is not valid JSON",
-    );
-
-    assert.ok(
-      execStub.calledOnceWithExactly(
-        `rbenv exec ruby -W0 -rjson '/fake/activation.rb'`,
-        {
-          cwd: workspacePath,
-          shell: vscode.env.shell,
-          // eslint-disable-next-line no-process-env
-          env: process.env,
-        },
-      ),
-    );
-
-    assert.ok(
-      errorStub.calledOnceWithExactly(
-        "Tried parsing invalid JSON environment: not a json",
-      ),
-    );
-
-    execStub.restore();
-    errorStub.restore();
-  });
 });
diff --git a/vscode/src/test/suite/ruby/rubyInstaller.test.ts b/vscode/src/test/suite/ruby/rubyInstaller.test.ts
index 21136ef99..58b782b31 100644
--- a/vscode/src/test/suite/ruby/rubyInstaller.test.ts
+++ b/vscode/src/test/suite/ruby/rubyInstaller.test.ts
@@ -133,6 +133,7 @@ suite("RubyInstaller", () => {
     const windows = new RubyInstaller(
       workspaceFolder,
       outputChannel,
+      context,
       async () => {},
     );
     const result = [
diff --git a/vscode/src/test/suite/ruby/rvm.test.ts b/vscode/src/test/suite/ruby/rvm.test.ts
index 7feab4d47..e1526b02e 100644
--- a/vscode/src/test/suite/ruby/rvm.test.ts
+++ b/vscode/src/test/suite/ruby/rvm.test.ts
@@ -9,7 +9,11 @@ import sinon from "sinon";
 import { Rvm } from "../../../ruby/rvm";
 import { WorkspaceChannel } from "../../../workspaceChannel";
 import * as common from "../../../common";
-import { ACTIVATION_SEPARATOR } from "../../../ruby/versionManager";
+import {
+  ACTIVATION_SEPARATOR,
+  FIELD_SEPARATOR,
+  VALUE_SEPARATOR,
+} from "../../../ruby/versionManager";
 
 suite("RVM", () => {
   if (os.platform() === "win32") {
@@ -54,28 +58,28 @@ suite("RVM", () => {
         ),
       );
 
-    const envStub = {
-      env: {
-        ANY: "true",
-      },
-      yjit: true,
-      version: "3.0.0",
-    };
+    const envStub = [
+      "3.0.0",
+      "/path/to/gems",
+      "true",
+      `ANY${VALUE_SEPARATOR}true`,
+    ].join(FIELD_SEPARATOR);
 
     const execStub = sinon.stub(common, "asyncExec").resolves({
       stdout: "",
-      stderr: `${ACTIVATION_SEPARATOR}${JSON.stringify(envStub)}${ACTIVATION_SEPARATOR}`,
+      stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
     });
 
     const { env, version, yjit } = await rvm.activate();
 
     assert.ok(
       execStub.calledOnceWithExactly(
-        `${path.join(os.homedir(), ".rvm", "bin", "rvm-auto-ruby")} -W0 -rjson '/fake/activation.rb'`,
+        `${path.join(os.homedir(), ".rvm", "bin", "rvm-auto-ruby")} -EUTF-8:UTF-8 '/fake/activation.rb'`,
         {
           cwd: workspacePath,
           shell: vscode.env.shell,
           env: process.env,
+          encoding: "utf-8",
         },
       ),
     );