From 8cf12f3192ae4150da67ee26e99ea16c757b5905 Mon Sep 17 00:00:00 2001 From: Moltar Date: Fri, 3 Apr 2026 13:44:28 -0400 Subject: [PATCH] fix(config): handle non-string config payloads safely --- api/src/services/openclawConfigService.js | 17 +++++++++++++++-- web/src/pages/OpenClawConfigSettings.jsx | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/api/src/services/openclawConfigService.js b/api/src/services/openclawConfigService.js index 0e8bdb6..4a34b3e 100644 --- a/api/src/services/openclawConfigService.js +++ b/api/src/services/openclawConfigService.js @@ -11,6 +11,19 @@ function createHttpError(status, message, code, details) { return error; } +function normalizeRawConfig(value) { + if (!value) return ''; + if (typeof value === 'string') return value; + if (typeof value === 'object') { + try { + return JSON.stringify(value, null, 2); + } catch { + return ''; + } + } + return String(value); +} + function restoreRedactedPlaceholders({ submittedRaw, currentRaw, userId }) { if (!submittedRaw.includes('__OPENCLAW_REDACTED__') || !currentRaw) { return submittedRaw; @@ -74,7 +87,7 @@ function restoreRedactedPlaceholders({ submittedRaw, currentRaw, userId }) { async function getConfig() { const result = await gatewayWsRpc('config.get', {}); return { - raw: result.raw || result.config || '', + raw: normalizeRawConfig(result.raw ?? result.config), hash: result.hash || null, }; } @@ -104,7 +117,7 @@ async function applyConfig({ userId, userRole, raw, baseHash, note }) { } const currentHash = currentConfig.hash || null; - const currentRaw = currentConfig.raw || currentConfig.config || ''; + const currentRaw = normalizeRawConfig(currentConfig.raw ?? currentConfig.config); if (currentHash && baseHash !== currentHash) { const conflict = createHttpError( diff --git a/web/src/pages/OpenClawConfigSettings.jsx b/web/src/pages/OpenClawConfigSettings.jsx index 933eff2..62a31cb 100644 --- a/web/src/pages/OpenClawConfigSettings.jsx +++ b/web/src/pages/OpenClawConfigSettings.jsx @@ -362,7 +362,7 @@ export default function OpenClawConfigSettings() { setConflictData(null); }; - const hasRedactedValues = raw.includes('__OPENCLAW_REDACTED__'); + const hasRedactedValues = typeof raw === 'string' && raw.includes('__OPENCLAW_REDACTED__'); const handleSave = async () => { if (isSaving || !canEdit) return;