From 612a9299070b6d78a69651cecf9d6db11b24345e Mon Sep 17 00:00:00 2001
From: Zhu Lei <123629497+kabishou11@users.noreply.github.com>
Date: Thu, 3 Sep 2026 07:51:41 +0000
Subject: [PATCH] fix(web): stringify object editor values before Monaco
createModel (#41719)
---
.../__tests__/index-logic.spec.tsx | 22 ++++++++++++++++
.../code-editor/__tests__/index.spec.tsx | 26 +++++++++++++++++++
.../code-editor/__tests__/utils.spec.ts | 16 ++++++++++++
.../components/editor/code-editor/index.tsx | 10 ++-----
.../components/editor/code-editor/utils.ts | 21 +++++++++++++++
5 files changed, 87 insertions(+), 8 deletions(-)
create mode 100644 web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/index.spec.tsx
create mode 100644 web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/utils.spec.ts
create mode 100644 web/app/components/workflow/nodes/_base/components/editor/code-editor/utils.ts
diff --git a/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx b/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx
index 603d5991704..16f22f59f78 100644
--- a/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx
+++ b/web/app/components/app/configuration/config-var/config-modal/__tests__/index-logic.spec.tsx
@@ -176,4 +176,26 @@ describe('ConfigModal logic', () => {
expect(latestFormProps?.modelId).toBe('model-1')
})
+
+ it('should pass object json_schema to the editor as JSON text', () => {
+ const jsonSchema = {
+ type: 'object',
+ properties: {
+ id: { type: 'string' },
+ name: { type: 'string' },
+ },
+ required: ['id', 'name'],
+ }
+
+ renderConfigModal(
+ createPayload({
+ type: InputVarType.jsonObject,
+ label: 'dsmworksheet',
+ variable: 'dsmworksheet',
+ json_schema: jsonSchema as InputVar['json_schema'],
+ }),
+ )
+
+ expect(latestFormProps?.jsonSchemaStr).toBe(JSON.stringify(jsonSchema, null, 2))
+ })
})
diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/index.spec.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/index.spec.tsx
new file mode 100644
index 00000000000..41083443e2e
--- /dev/null
+++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/index.spec.tsx
@@ -0,0 +1,26 @@
+import { render, screen } from '@testing-library/react'
+import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
+import CodeEditor from '..'
+
+vi.mock('@/hooks/use-theme', () => ({
+ default: () => ({ theme: 'light' }),
+}))
+
+const jsonObjectSchema = {
+ type: 'object',
+ properties: {
+ id: { type: 'string' },
+ name: { type: 'string' },
+ },
+ required: ['id', 'name'],
+}
+
+describe('CodeEditor', () => {
+ it('serializes object JSON values so Monaco receives text instead of a buffer factory', () => {
+ render()
+
+ expect(screen.getByTestId('monaco-editor')).toHaveValue(
+ JSON.stringify(jsonObjectSchema, null, 2),
+ )
+ })
+})
diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/utils.spec.ts b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/utils.spec.ts
new file mode 100644
index 00000000000..747dd1a40ab
--- /dev/null
+++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/__tests__/utils.spec.ts
@@ -0,0 +1,16 @@
+import { serializeCodeEditorValue } from '../utils'
+
+describe('serializeCodeEditorValue', () => {
+ it('turns object values into JSON text so Monaco does not treat them as a buffer factory', () => {
+ const schema = {
+ type: 'object',
+ properties: { id: { type: 'string' } },
+ }
+
+ expect(serializeCodeEditorValue(schema)).toBe(JSON.stringify(schema, null, 2))
+ expect(serializeCodeEditorValue(schema, true)).toBe(JSON.stringify(schema, null, 2))
+ expect(serializeCodeEditorValue('{"type":"object"}')).toBe('{"type":"object"}')
+ expect(serializeCodeEditorValue(undefined)).toBe('')
+ expect(serializeCodeEditorValue(null as never)).toBe('')
+ })
+})
diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx
index 2fb7fe4ae58..893cf6d1e29 100644
--- a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx
+++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx
@@ -11,6 +11,7 @@ import useTheme from '@/hooks/use-theme'
import { Theme } from '@/types/app'
import { basePath } from '@/utils/var'
import Base from '../base'
+import { serializeCodeEditorValue } from './utils'
import './style.css'
// load file from local instead of cdn https://github.com/suren-atoyan/monaco-react/issues/482
@@ -117,14 +118,7 @@ const CodeEditor: FC = ({
setIsMounted(true)
}
- const outPutValue = (() => {
- if (!isJSONStringifyBeauty) return value as string
- try {
- return JSON.stringify(value as object, null, 2)
- } catch {
- return value as string
- }
- })()
+ const outPutValue = serializeCodeEditorValue(value, isJSONStringifyBeauty)
const theme = useMemo(() => {
if (appTheme === Theme.light) return 'light'
diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/utils.ts b/web/app/components/workflow/nodes/_base/components/editor/code-editor/utils.ts
new file mode 100644
index 00000000000..6d5ae777931
--- /dev/null
+++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/utils.ts
@@ -0,0 +1,21 @@
+export const serializeCodeEditorValue = (
+ value?: string | object,
+ isJSONStringifyBeauty?: boolean,
+): string => {
+ if (value == null) return ''
+
+ if (!isJSONStringifyBeauty) {
+ if (typeof value === 'string') return value
+ try {
+ return JSON.stringify(value, null, 2)
+ } catch {
+ return ''
+ }
+ }
+
+ try {
+ return JSON.stringify(value, null, 2)
+ } catch {
+ return typeof value === 'string' ? value : ''
+ }
+}