{"record":{"id":"47b9dc1d6033e062","repo":"QuantumNous/new-api","slug":"legacy-format-must-be-a-json-object","errorCode":null,"errorMessage":"Legacy format must be a JSON object","messagePattern":"Legacy format must be a JSON object","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/src/features/channels/components/dialogs/param-override-editor-dialog.tsx","lineNumber":1486,"sourceCode":"      }\n      resetDragState()\n    },\n    [draggedOperationId, dragOverOperationId, dragOverPosition, resetDragState]\n  )\n\n  // ---------------------------------------------------------------------------\n  // Mode switching & templates\n  // ---------------------------------------------------------------------------\n\n  const buildVisualJson = useCallback((): string => {\n    if (visualMode === 'legacy') {\n      const trimmed = legacyValue.trim()\n      if (!trimmed) return ''\n      if (!verifyJSON(trimmed))\n        throw new Error(t('Parameter override must be valid JSON format'))\n      const parsed = JSON.parse(trimmed) as unknown\n      if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))\n        throw new Error(t('Legacy format must be a JSON object'))\n      return JSON.stringify(parsed, null, 2)\n    }\n    return buildOperationsJson(operations, { validate: true }, t)\n  }, [legacyValue, operations, t, visualMode])\n\n  const switchToJsonMode = useCallback(() => {\n    if (editMode === 'json') return\n    try {\n      setJsonText(buildVisualJson())\n      setJsonError('')\n    } catch (error) {\n      toast.error((error as Error).message)\n      if (visualMode === 'legacy') {\n        setJsonText(legacyValue)\n      } else {\n        setJsonText(buildOperationsJson(operations, { validate: false }, t))\n      }\n      setJsonError(","sourceCodeStart":1468,"sourceCodeEnd":1504,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/features/channels/components/dialogs/param-override-editor-dialog.tsx#L1468-L1504","documentation":"Thrown by buildVisualJson when the legacy text is syntactically valid JSON but JSON.parse yields null, a primitive (string/number/boolean), or an Array. The override format requires a top-level JSON object, so anything else is rejected before re-serialization.","triggerScenarios":"Legacy field contains e.g. [\"gpt-4o\"] (array), \"gpt-4o\" (bare string), 42, or the literal null — parse succeeds, the object check fails, and this error is toasted during the mode switch.","commonSituations":"User wrapped the override in brackets thinking it is a list of overrides; pasted a single string value; copied a JSON fragment from a config that stores overrides as an array.","solutions":["Wrap the content in a top-level object: change [\"k\":\"v\"] to {\"k\":\"v\"}","If the value is a bare primitive, give it a key, e.g. \"gpt-4o\" → {\"model\": \"gpt-4o\"}","Check for null literal — an empty field is fine (returns early) but the text null is not","Validate shape in a console: JSON.parse(text) must give typeof 'object' and not Array.isArray"],"exampleFix":"// before\n[\n  { \"upstream\": \"openai\" }\n]\n// after\n{\n  \"upstream\": \"openai\"\n}","handlingStrategy":"type-guard","validationCode":"const parsed = JSON.parse(trimmed) as unknown\nconst isJsonObject = !!parsed && typeof parsed === 'object' && !Array.isArray(parsed)\nif (!isJsonObject) { /* show inline shape error */ }","typeGuard":"const isPlainObject = (v: unknown): v is Record<string, unknown> =>\n  typeof v === 'object' && v !== null && !Array.isArray(v)","tryCatchPattern":"try {\n  const parsed: unknown = JSON.parse(trimmed)\n  if (!isPlainObject(parsed)) throw new Error(t('Legacy format must be a JSON object'))\n} catch (error) {\n  toast.error((error as Error).message)\n}","preventionTips":["Apply isPlainObject immediately after parse everywhere override JSON is accepted","Show an example object placeholder in the textarea to guide shape","Document that arrays and primitives are rejected at the top level"],"tags":["validation","json","param-override","shape-error"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}