Skip to content

Invalid query validation should return 400 Bad Request instead of 500 Server Error #3813

Description

@hecateball

Is your feature request related to a problem? Please describe

When an invalid SQL query is sent to the query API endpoint(POST /__nuxt_content/[collection]/query), the assertSafeQuery() function throws an error that is not properly caught. This results in an HTTP 500 Server Error being returned to the client, when it should return HTTP 400 Bad Request instead.
Query validation errors (client-side mistakes) should be treated as client errors (4xx) rather than server errors (5xx).

This is causing critical issues for production applications:

  • Our application servers have monitoring systems that detect HTTP 5xx responses and trigger critical alerts. Invalid query validation errors are being incorrectly classified as server errors, causing our alert systems to fire even though there is no actual server problem.
  • According to standard HTTP status code conventions and REST API best practices, validation errors on client input should return 400 Bad Request, not 500 Server Error. Returning 500 violates these conventions and makes it difficult for client applications to properly handle and differentiate between validation errors and actual server failures.

Describe the solution you’d like

The error is thrown in src/runtime/api/query.post.ts, where assertSafeQuery() is called without error handling:

export default eventHandler(async (event) => {
  const { sql } = await readBody(event)
  const collection = getRouterParam(event, ‘collection’)! || event.path?.split(/)?.[2] || ‘’

  assertSafeQuery(sql, collection)  // ← Unhandled error becomes 500

  const conf = useRuntimeConfig().content as RuntimeConfig[‘content’]
  if (conf.integrityCheck) {
    await checkAndImportDatabaseIntegrity(event, collection, conf)
  }

  return loadDatabaseAdapter(conf).all(sql)
})

Wrap the assertSafeQuery() call in a try-catch block and return a proper 400 error response:

  try {
    assertSafeQuery(sql, collection)
  } catch (error) {
    throw createError({
      statusCode: 400,
      statusMessage: ‘Bad Request’,
      data: {
        message: error instanceof Error ? error.message : ‘Invalid query’
      }
    })
  }

Describe alternatives you’ve considered

assertSafeQuery() itself may throw error with statusCode: 400 rather than wrapping the function.

Additional context

  • File affected: src/runtime/api/query.post.ts
  • Function: assertSafeQuery() in src/runtime/internal/security.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions