Budibase/budibase · error
Parameter '${key}' input contains a handlebars binding - thi
Error message
Parameter '${key}' input contains a handlebars binding - this is not allowed. What it means
`validateQueryInputs` rejects query parameter values that contain Handlebars `{{...}}` blocks. Parameters with literal handlebars bindings would be evaluated or leak binding syntax into requests, so any string parameter containing `{{` blocks throws this error. It is invoked via `enrichParameters` when query inputs are saved or executed.
Source
Thrown at packages/server/src/api/controllers/query/index.ts:79
timeoutMs: env.QUERY_THREAD_TIMEOUT,
})
function sanitiseUserStructure(user: ContextUser) {
const copiedUser = cloneDeep(user)
delete copiedUser.roles
delete copiedUser.account
delete copiedUser.license
return copiedUser
}
function validateQueryInputs(parameters: QueryEventParameters) {
for (let entry of Object.entries(parameters)) {
const [key, value] = entry
if (typeof value !== "string") {
continue
}
if (findHBSBlocks(value).length !== 0) {
throw new Error(
`Parameter '${key}' input contains a handlebars binding - this is not allowed.`
)
}
}
}
export async function fetchQueries(ctx: UserCtx<void, FetchQueriesResponse>) {
ctx.body = await sdk.queries.fetch()
}
const _import = async (
ctx: UserCtx<ImportRestQueryRequest, ImportRestQueryResponse>
) => {
const body = ctx.request.body
const importerInput = body.restTemplateId
? { data: await sdk.restTemplates.getSpec(body.restTemplateId) }
: body
const importer = await createImporter(importerInput)View on GitHub (pinned to a81a902e9a)
Solutions
- Remove the `{{...}}` text from the parameter value and enter the raw literal value
- Configure the dynamic part as a binding in the query definition itself rather than in the default parameter value
- If the value legitimately contains double braces, escape or restructure it so `findHBSBlocks` finds no match
- Update the saved query/API request body to use proper interpolation syntax supported by the query editor
Example fix
// before
parameters: { userId: "{{ user._id }}" }
// after
parameters: { userId: "1234" } // and bind {{ userId }} in the query string Defensive patterns
Strategy: validation
Validate before calling
const hasHbs = (v) => typeof v === "string" && /\{\{[\s\S]*?\}\}/.test(v)
const clean = Object.fromEntries(Object.entries(params).filter(([, v]) => !hasHbs(v))) Try / catch
try {
await api.saveQuery({ parameters })
} catch (e) {
if (String(e.message).includes("handlebars binding")) {
// strip bindings and retry with literal values
}
} Prevention
- Never paste templated URLs/payloads directly into parameter defaults
- Use the binding drawer in the query editor instead of typing {{ }} manually
- Sanitize user-provided parameter values before submitting
- Remember: bindings belong in the query string/body, not in parameter values
When it happens
Trigger: Saving or running a REST/SQL query where any entry in the `parameters` object is a string containing a handlebars block, e.g. `{ name: "{{user.id}}" }`. Only string values are checked; other types pass through.
Common situations: A user pastes a URL or payload copied from another tool that already contains `{{...}}` templating; UI binding was accidentally typed as literal text instead of bound through the binding picker; migrating queries where dynamic values should be declared in the query string, not in default parameter values.
Related errors
- Cannot process non-string types.
- Multi-object JSON templates must be valid JSON objects
- Error getting status
- Unable to remove doc without a valid _id and _rev.
- Cannot store document without _id field.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/23dcc04dbbde1d11.
Report an issue: GitHub.