QuantumNous/new-api · warning · Error
Legacy format must be a JSON object
Error message
Legacy format must be a JSON object
What it means
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.
Source
Thrown at web/src/features/channels/components/dialogs/param-override-editor-dialog.tsx:1486
}
resetDragState()
},
[draggedOperationId, dragOverOperationId, dragOverPosition, resetDragState]
)
// ---------------------------------------------------------------------------
// Mode switching & templates
// ---------------------------------------------------------------------------
const buildVisualJson = useCallback((): string => {
if (visualMode === 'legacy') {
const trimmed = legacyValue.trim()
if (!trimmed) return ''
if (!verifyJSON(trimmed))
throw new Error(t('Parameter override must be valid JSON format'))
const parsed = JSON.parse(trimmed) as unknown
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
throw new Error(t('Legacy format must be a JSON object'))
return JSON.stringify(parsed, null, 2)
}
return buildOperationsJson(operations, { validate: true }, t)
}, [legacyValue, operations, t, visualMode])
const switchToJsonMode = useCallback(() => {
if (editMode === 'json') return
try {
setJsonText(buildVisualJson())
setJsonError('')
} catch (error) {
toast.error((error as Error).message)
if (visualMode === 'legacy') {
setJsonText(legacyValue)
} else {
setJsonText(buildOperationsJson(operations, { validate: false }, t))
}
setJsonError(View on GitHub (pinned to e2c7aa7b10)
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
Example fix
// before
[
{ "upstream": "openai" }
]
// after
{
"upstream": "openai"
} Defensive patterns
Strategy: type-guard
Validate before calling
const parsed = JSON.parse(trimmed) as unknown
const isJsonObject = !!parsed && typeof parsed === 'object' && !Array.isArray(parsed)
if (!isJsonObject) { /* show inline shape error */ } Type guard
const isPlainObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v)
Try / catch
try {
const parsed: unknown = JSON.parse(trimmed)
if (!isPlainObject(parsed)) throw new Error(t('Legacy format must be a JSON object'))
} catch (error) {
toast.error((error as Error).message)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Parameter override must be valid JSON format
- JSON must be an object
- Channel is not selected
- Unexpected release payload
AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15).
Data as JSON: /api/errors/47b9dc1d6033e062.
Report an issue: GitHub.