Budibase/budibase · error
Multi-object JSON templates must be valid JSON objects
Error message
Multi-object JSON templates must be valid JSON objects
What it means
processJsonStringSync in packages/string-templates/src/index.ts renders a template that must produce a valid JSON object. When interpolation of the (multi-object) JSON template fails and the parsed result cannot be assembled as a JSON object, it throws "Multi-object JSON templates must be valid JSON objects". The template's output is expected to be parseable JSON after bindings are substituted.
Source
Thrown at packages/string-templates/src/index.ts:491
// reopens quote-breaking operator injection for multi-object templates.
try {
return documents
.map(document => {
const preparedDocument = quoteRawJsonBindings(document)
const parsed = JSON.parse(
preparedDocument.template
) as JsonTemplateValue
return processJsonTemplateValue(
parsed,
preparedDocument.bindings,
context,
opts
)
})
.map(value => JSON.stringify(value))
.join(" ")
} catch {
throw new Error("Multi-object JSON templates must be valid JSON objects")
}
}
}
/**
* Same as function above, but allows logging to be returned - this is only for JS bindings.
*/
export function processStringWithLogsSync(
string: string,
context?: object,
opts?: ProcessOptions
): { result: string; logs: Log[] } {
if (isBackendService()) {
throw new Error("Logging disabled for backend bindings")
}
return processStringSyncInternal(string, context, {
...opts,
logging: true,View on GitHub (pinned to a81a902e9a)
Solutions
- Quote string bindings and escape/JSON-stringify values before interpolation (use a helper that emits JSON.stringify(value)).
- Validate the template by rendering it and running JSON.parse on the result in a test.
- Replace object-valued bindings with their string/JSON-serialised equivalents.
- Simplify to a single JSON object template, or construct the payload with code instead of string templating.
Example fix
// before
`{ "name": {{user.name}} }` // user.name = O"Brien -> invalid JSON
// after
`{ "name": {{JSONstringify user.name}} }` // binding emitted as "O\"Brien" Defensive patterns
Strategy: validation
Validate before calling
function jsonSafe(v: unknown): string {
return JSON.stringify(v) // emits a quoted, escaped JSON token
}
// build the template with jsonSafe bindings, then verify:
const rendered = processJsonStringSync(template, context)
JSON.parse(rendered) // throws early if still invalid Type guard
function isValidJson(v: string): boolean {
try { JSON.parse(v); return true } catch { return false }
} Try / catch
let payload: unknown
try {
const raw = processJsonStringSync(template, context)
payload = JSON.parse(raw)
} catch (e) {
if (e.message.includes("must be valid JSON objects") || e instanceof SyntaxError) {
payload = { fallback: true }
} else throw e
} Prevention
- Always JSON-stringify bindings that contain user text before interpolation
- Keep string bindings inside quotes in the JSON template
- Test-render templates with adversarial inputs (quotes, newlines) and JSON.parse the result
- Construct JSON payloads programmatically instead of string templating where possible
When it happens
Trigger: Using a JSON template whose bindings inject values that break JSON syntax: raw strings containing unescaped quotes, multiline strings, values that are objects/arrays rather than scalars, or bindings producing nothing where a required token is expected.
Common situations: Building request bodies for REST/API steps where a context binding contains user text with quotes; passing objects (instead of strings/scalars) into {{ }} placeholders inside JSON templates; templates edited by hand with trailing commas or missing quotes around string bindings.
Related errors
- Parameter '${key}' input contains a handlebars binding - thi
- Invalid agent request outcome response
- Project package contains invalid JSON in '${basename(filePat
- Project package contains an invalid doc in '${basename(fileP
- Cannot process non-string types.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/263751ca29653330.
Report an issue: GitHub.