From afd0fe32c286b657ea17bb3fd296e62385e4b337 Mon Sep 17 00:00:00 2001 From: xingzhou Date: Fri, 17 Jul 2026 09:26:26 +0800 Subject: [PATCH] fix(qa-lab): preserve boundary emoji in gateway startup diagnostics (#104840) Co-authored-by: Peter Steinberger --- extensions/qa-lab/src/gateway-child.test.ts | 12 ++++++++++++ extensions/qa-lab/src/gateway-child.ts | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/extensions/qa-lab/src/gateway-child.test.ts b/extensions/qa-lab/src/gateway-child.test.ts index 7c2295ed0089..567c59475449 100644 --- a/extensions/qa-lab/src/gateway-child.test.ts +++ b/extensions/qa-lab/src/gateway-child.test.ts @@ -206,6 +206,18 @@ describe("formatQaGatewayProcessBoundaryStartupFailure", () => { expect(message).not.toContain("s".repeat(100)); expect(message).not.toContain(prefix); }); + + it("preserves complete Unicode code points at the retained log-tail boundary", () => { + const message = testing.formatQaGatewayProcessBoundaryStartupFailure( + new Error("launcher exited before identity"), + `P😀${"z".repeat(8_191)}`, + ); + + expect(message).not.toMatch( + /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(? { diff --git a/extensions/qa-lab/src/gateway-child.ts b/extensions/qa-lab/src/gateway-child.ts index edba1decf248..2f8c051ad354 100644 --- a/extensions/qa-lab/src/gateway-child.ts +++ b/extensions/qa-lab/src/gateway-child.ts @@ -18,6 +18,7 @@ import { uniqueStrings, } from "openclaw/plugin-sdk/string-coerce-runtime"; import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path"; +import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime"; import { createQaBundledPluginsDir, resolveQaBundledPluginSourceDir, @@ -493,7 +494,10 @@ function monitorQaGatewayChildFailure(child: ChildProcess, output: { push(chunk: const QA_GATEWAY_PROCESS_BOUNDARY_LOG_TAIL_CHARS = 8_192; function formatQaGatewayProcessBoundaryStartupFailure(error: unknown, logs: string) { - const logTail = redactQaGatewayDebugText(logs).slice(-QA_GATEWAY_PROCESS_BOUNDARY_LOG_TAIL_CHARS); + const logTail = sliceUtf16Safe( + redactQaGatewayDebugText(logs), + -QA_GATEWAY_PROCESS_BOUNDARY_LOG_TAIL_CHARS, + ); return `${formatErrorMessage(error)}${formatQaGatewayLogsForError(logTail)}`; }