brianc/node-postgres · error · TypeError

Client was passed a null or undefined query

Error message

Client was passed a null or undefined query

What it means

A TypeError thrown synchronously by the native Client's query() method when the first argument (config) is null or undefined. The method accepts a string, an object, or a Query instance as the first argument — but explicitly rejects null and undefined to fail fast rather than producing a confusing downstream error.

Solutions

  1. Ensure the first argument to query() is always a string, object, or Query instance — never null or undefined.
  2. Add a guard clause before calling query() to check the argument is defined.
  3. If the query text comes from user input, validate it exists and is a non-empty string before passing.
  4. Use TypeScript to catch null/undefined at compile time with strict null checks.

Example fix

// before — queryText may be undefined
const queryText = req.body.query // could be undefined
await client.query(queryText)

// after — guard before calling
const queryText = req.body.query
if (!queryText) {
  throw new Error('Query text is required')
}
await client.query(queryText)
Defensive patterns

Strategy: validation

Validate before calling

function safeQuery(client, config, values, callback) {
  if (config === null || config === undefined) {
    throw new TypeError('Query config is required — received ' + String(config))
  }
  return client.query(config, values, callback)
}

Type guard

// TypeScript: narrow the query input type
function isValidQueryConfig(config: unknown): config is string | object {
  return config !== null && config !== undefined && (typeof config === 'string' || typeof config === 'object')
}

// Usage:
if (!isValidQueryConfig(queryInput)) {
  throw new Error('Invalid query input')
}
await client.query(queryInput)

Try / catch

try {
  await client.query(config)
} catch (err) {
  if (err instanceof TypeError && err.message.includes('null or undefined query')) {
    throw new Error('Query was called without a valid config — check the caller provides a query string or object')
  }
  throw err
}

Prevention

When it happens

Trigger: Calling nativeClient.query(null) or nativeClient.query(undefined). This happens when a variable intended to hold the query text or config object was never assigned, conditionally set to null, or came from an object property that doesn't exist (e.g., req.body.query when the body has no query field). The check is at native/client.js:167-168.

Common situations: Building a query string from a variable that was conditionally set and the condition wasn't met; destructuring a config object where a property is missing; passing an expression like req.body.sortBy that evaluates to undefined; refactoring that accidentally passes the wrong variable.

Related errors


AI-assisted analysis of brianc/node-postgres@ff9d775abd (2026-08-11). Data as JSON: /api/errors/30d23418be548ab1. Report an issue: GitHub.

Appendix: source

Thrown at packages/pg/lib/native/client.js:168

// send a query to the server
// this method is highly overloaded to take
// 1) string query, optional array of parameters, optional function callback
// 2) object query with {
//    string query
//    optional array values,
//    optional function callback instead of as a separate parameter
//    optional string name to name & cache the query plan
//    optional string rowMode = 'array' for an array of results
//  }
Client.prototype.query = function (config, values, callback) {
  let query
  let result
  let readTimeout
  let readTimeoutTimer
  let queryCallback

  if (config === null || config === undefined) {
    throw new TypeError('Client was passed a null or undefined query')
  } else if (typeof config.submit === 'function') {
    readTimeout = config.query_timeout || this.connectionParameters.query_timeout
    result = query = config
    // accept query(new Query(...), (err, res) => { }) style
    if (typeof values === 'function') {
      config.callback = values
    }
  } else {
    readTimeout = config.query_timeout || this.connectionParameters.query_timeout
    query = new NativeQuery(config, values, callback)
    if (!query.callback) {
      let resolveOut, rejectOut
      result = new this._Promise((resolve, reject) => {
        resolveOut = resolve
        rejectOut = reject
      }).catch((err) => {
        Error.captureStackTrace(err)
        throw err

View on GitHub (pinned to ff9d775abd)