fastify/fastify · error · Error
FST_ERR_SCH_DUPLICATE
FST_ERR_SCH_DUPLICATE
Error message
Schema with '%s' already present!
What it means
Thrown by normalizeSchema (lib/schemas.js:67) when a route schema defines both query and querystring keys. Fastify treats query as an alias for querystring and copies it over; defining both is ambiguous, so it is rejected to prevent silent shadowing.
Source
Thrown at lib/schemas.js:67
* Checks whether a schema is a non-plain object.
*
* @param {*} schema the schema to check
* @returns {boolean} true if schema has a custom prototype
*/
function isCustomSchemaPrototype (schema) {
return typeof schema === 'object' && Object.getPrototypeOf(schema) !== Object.prototype
}
function normalizeSchema (routeSchemas, serverOptions) {
if (routeSchemas[kSchemaVisited]) {
return routeSchemas
}
// alias query to querystring schema
if (routeSchemas.query) {
// check if our schema has both querystring and query
if (routeSchemas.querystring) {
throw new FST_ERR_SCH_DUPLICATE('querystring')
}
routeSchemas.querystring = routeSchemas.query
}
generateFluentSchema(routeSchemas)
for (const key of SCHEMAS_SOURCE) {
const schema = routeSchemas[key]
if (schema && !isCustomSchemaPrototype(schema)) {
if (key === 'body' && schema.content) {
const contentProperty = schema.content
const keys = Object.keys(contentProperty)
for (let i = 0; i < keys.length; i++) {
const contentType = keys[i]
const contentSchema = contentProperty[contentType].schema
if (!contentSchema) {
throw new FST_ERR_SCH_CONTENT_MISSING_SCHEMA(contentType)
}View on GitHub (pinned to 7299a57d3f)
Solutions
- Keep only one of query or querystring in each route schema (query is the preferred short alias).
- If merging schema fragments programmatically, delete the duplicate key before passing to Fastify.
- Standardise your codebase on a single key name.
Example fix
// before
fastify.get('/x', { schema: { query: { type: 'object' }, querystring: { type: 'object' } } }, handler)
// after
fastify.get('/x', { schema: { querystring: { type: 'object' } } }, handler) Defensive patterns
Strategy: validation
Validate before calling
function normalizeQueryAlias (schema) {
if (schema && schema.query && schema.querystring) {
throw new Error('Define only one of schema.query or schema.querystring')
}
} Prevention
- Standardise the codebase on a single key (querystring or query).
- When merging schema fragments, delete the duplicate alias before registering.
- Lint route schemas in a factory to catch the dual-key case.
When it happens
Trigger: fastify.get('/x', { schema: { query: { ... }, querystring: { ... } } }, handler). Copy-pasting between Fastify versions (older docs used querystring, examples now show query) and ending up with both.
Common situations: Migrating from older Fastify samples. Combining schemas from different team members where one used query and the other querystring. Generic schema factories that merge objects and accidentally produce both keys.
Related errors
- FST_ERR_DUPLICATED_ROUTE
- FST_ERR_SCH_VALIDATION_BUILD
- FST_ERR_SCH_SERIALIZATION_BUILD
- FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED
- FST_ERR_SCH_ALREADY_PRESENT
AI-assisted analysis of fastify/fastify@7299a57d3f (2026-08-03).
Data as JSON: /data/errors/4ee3e82b86bba1ab.json.
Report an issue: GitHub.