sequelize/sequelize · error · TypeError
Sequelize#rawQuery requires a string as the first parameter.
Error message
Sequelize#rawQuery requires a string as the first parameter.
What it means
queryRaw is the low-level variant of query that does *not* process replacements. It requires the first parameter to be a string so the dialect's bind-parameter mapper can scan it. Line 254 throws TypeError on any non-string input, catching mistakes where users route a sql expression or options object through queryRaw.
Source
Thrown at packages/core/src/sequelize.js:255
'"sql" cannot be an object. Pass a string instead, and pass bind and replacement parameters through the "options" parameter',
);
}
sql = sql.trim();
if (options.replacements) {
sql = injectReplacements(sql, this.dialect, options.replacements);
}
// queryRaw will throw if 'replacements' is specified, as a way to warn users that they are miusing the method.
delete options.replacements;
return this.queryRaw(sql, options);
}
async queryRaw(sql, options) {
if (typeof sql !== 'string') {
throw new TypeError('Sequelize#rawQuery requires a string as the first parameter.');
}
if (options != null && 'replacements' in options) {
throw new TypeError(`Sequelize#rawQuery does not accept the "replacements" options.
Only bind parameters can be provided, in the dialect-specific syntax.
Use Sequelize#query if you wish to use replacements.`);
}
options = { ...this.options.query, ...options, bindParameterOrder: null };
let bindParameters;
if (options.bind != null) {
const isBindArray = Array.isArray(options.bind);
if (!isPlainObject(options.bind) && !isBindArray) {
throw new TypeError(
'options.bind must be either a plain object (for named parameters) or an array (for numeric parameters)',
);
}View on GitHub (pinned to 7e1deec499)
Solutions
- Ensure the first argument is a string literal or template: `sequelize.queryRaw('SELECT $1', { bind: [1] })`.
- If you have a sql`` expression, use `sequelize.query()` instead — it will format the BaseSqlExpression for you.
- Coerce/validate dynamic SQL to a string before calling queryRaw.
Example fix
// before
await sequelize.queryRaw(sql`SELECT ${1}`); // sql expression is not a string
// after
await sequelize.query(sql`SELECT ${1}`); // use query() for sql expressions
// or:
await sequelize.queryRaw('SELECT $1', { bind: [1] }); Defensive patterns
Strategy: type-guard
Validate before calling
function assertRawSqlString(sql) {
if (typeof sql !== 'string') {
throw new TypeError('queryRaw requires a string; for sql expressions use query() instead.');
}
return sql;
}
await sequelize.queryRaw(assertRawSqlString(sql), { bind }); Type guard
function isRawQueryString(sql) {
return typeof sql === 'string';
} Try / catch
try {
await sequelize.queryRaw(expr, { bind });
} catch (e) {
if (/requires a string as the first parameter/.test(e.message)) {
await sequelize.query(expr, { bind });
} else throw e;
} Prevention
- Reserve queryRaw for plain-string SQL only; route sql`` expressions through query().
- Add a lint rule discouraging queryRaw with non-string first args.
- Document in code comments when queryRaw is chosen over query and why.
When it happens
Trigger: Calling `sequelize.queryRaw(someObject)`, `sequelize.queryRaw(number)`, or passing a BaseSqlExpression that should have gone through `query()` instead.
Common situations: Refactoring and accidentally switching a `query` call to `queryRaw` while still passing an expression; calling queryRaw on user input that was not coerced to a string.
Related errors
- "sql" cannot be an object. Pass a string instead, and pass b
- options.bind must be either a plain object (for named parame
- The following literal includes positional replacements (?).
- Function ${piece.constructor.name} is not supported by ${thi
- Invalid Include received. Include has to be either a Model,
AI-assisted analysis of sequelize/sequelize@7e1deec499 (2026-08-03).
Data as JSON: /data/errors/642f93972a9cf502.json.
Report an issue: GitHub.