diff --git a/extensions/microsoft-foundry/cli.ts b/extensions/microsoft-foundry/cli.ts index 05c22df7887..9b65841ded9 100644 --- a/extensions/microsoft-foundry/cli.ts +++ b/extensions/microsoft-foundry/cli.ts @@ -4,6 +4,7 @@ import { normalizeOptionalString, normalizeStringifiedOptionalString, } from "openclaw/plugin-sdk/string-coerce-runtime"; +import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime"; import type { AzAccessToken, AzAccount } from "./shared.js"; import { COGNITIVE_SERVICES_RESOURCE } from "./shared.js"; @@ -34,7 +35,7 @@ function summarizeAzErrorMessage(raw: string): string { if (/aadsts\d+/i.test(normalized)) { return "Azure login failed for the selected tenant. Re-run `az login --use-device-code` and confirm the tenant is correct."; } - return normalized.slice(0, 300); + return truncateUtf16Safe(normalized, 300); } function buildAzCommandError(error: Error, stderr: string, stdout: string): Error { diff --git a/extensions/microsoft-foundry/index.test.ts b/extensions/microsoft-foundry/index.test.ts index 8ab1d902e67..f02a5502a98 100644 --- a/extensions/microsoft-foundry/index.test.ts +++ b/extensions/microsoft-foundry/index.test.ts @@ -1830,6 +1830,22 @@ describe("microsoft-foundry plugin", () => { await expect(getAccessTokenResultAsync()).rejects.toThrow("Azure CLI is not logged in"); }); + it("keeps bounded Azure CLI error details UTF-16 safe", async () => { + const prefix = "x".repeat(299); + execFileMock.mockImplementationOnce( + ( + _file: unknown, + _args: unknown, + _options: unknown, + callback: (error: Error | null, stdout: string, stderr: string) => void, + ) => callback(new Error("az failed"), "", `${prefix}😀tail`), + ); + + await expect(getAccessTokenResultAsync()).rejects.toMatchObject({ + message: `az failed: ${prefix}`, + }); + }); + it("deletes legacy provider-level secret refs", () => { const secretRef = { source: "env" as const,