New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Schema errors since Fastify 4 #4028
Comments
Are you actually trying to register the same schema (by |
@jsumners Actually no (at least not knowingly 🙂 ). There's only the |
I don't use the schema container you are referencing. So I don't know what you're stating. It sounds like either:
A reproduction repo would be most helpful. |
I have distilled this down into a minimal example: https://github.com/qqilihq/fastify-issue-4028 During this, I figured out that this one will cause the issue: image: Type.Union([Type.Ref(File), Type.Null()]), |
@fastify/typescript cc: @sinclairzx81 |
It is not related to Minimal repro extracted from https://github.com/qqilihq/fastify-issue-4028 import Fastify from "fastify";
const fastify = Fastify();
fastify.addSchema({
$id: "ObjectId",
type: "string",
});
fastify.addSchema({
$id: "File",
type: "object",
properties: {
_id: { $ref: "ObjectId" },
name: { type: "string" },
owner: { $ref: "ObjectId" },
},
});
fastify.addSchema({
$id: "Article",
type: "object",
properties: {
_id: {
$ref: "ObjectId",
},
name: {
type: "string",
},
image: {
anyOf: [
{
$ref: "File",
},
{
type: "null",
},
],
},
},
});
fastify.get(
"/",
{ schema: { response: { 200: { $ref: "Article" } } } },
() => {}
);
await fastify.ready(); |
@jsumners I had a quick look at this, and wasn't able to reproduce the duplicate ID error through Fastify, so for example, the following is ok. import { Type } from '@sinclair/typebox'
import Fastify from 'fastify'
const fastify = Fastify({
ajv: {
customOptions: {
keywords: ['kind', 'modifier']
}
}
})
const File = Type.Object({
name: Type.String(),
size: Type.Integer()
}, { $id: 'File' })
fastify.addSchema(File)
fastify.post('/', {
schema: {
body: Type.Object({
image: Type.Union([Type.Ref(File), Type.Null()]),
})
}
}, (req, res) => res.send('ok'))
fastify.listen({ port: 5000 }) But was able to get import { Type } from '@sinclair/typebox'
import Serialize from 'fast-json-stringify'
const File = Type.Object({
name: Type.String(),
size: Type.Integer()
}, { $id: 'File' })
const T = Type.Object({
image: Type.Union([Type.Ref(File), Type.Null()]),
})
Serialize(T, {
schema: { File },
// ajv: { schemas: { File } } // uncommenting this line produces the error
//
// Error: schema with key or id "File" already exists
}) Not sure if the second example might be a clue as to what error might be occurring, but for all intents and purposes, the reference external schema should be working ok (as per the users example). Hope that helps |
As part of the error handling refactoring of #3261, we should not be setting a custom status code for validation routes. We should rely only on the error.statusCode property instead and leave the user full customization capabilities. Unfortunately a change was missed. Fixes: #4028 Ref: #3261 Signed-off-by: Matteo Collina <hello@matteocollina.com>
This was fixed by #4049 |
You can try main if you'd like. It'll likely go out next week. |
First: Thank you all for your efforts! Unfortunately, it still doesn't work for me. I have updated the repro repo above, and I still get:
|
@qqilihq I think the error is actually correct, you are reusing the same objectid twice. |
@mcollina Thanks for the reply. Actually (knowingly) I define it only once end then use https://github.com/qqilihq/fastify-issue-4028/blob/main/src/schemas/file.schema.ts#L6 If there's something I'm misunderstanding fundamentally, I'll be happy for any hint :-) |
How do I run that project? It doesn't seem to start or generate an error. |
git clone https://github.com/qqilihq/fastify-issue-4028.git
cd fastify-issue-4028
yarn
yarn start |
The problem is caused by |
@mcollina I can indeed confirm that this fixes the issue with the sample project posted above, thank you! Unfortunately, I still get an error in my real, more complex project for a |
fastify/fast-json-stringify#470 solves the problem. Update your deps, it work for me now! |
Yeah -- this worked! Thank you so much! |
Prerequisites
Fastify version
4.0.3
Plugin version
No response
Node.js version
16.13.0
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
11.6.6
Description
First: Thank you for your work on Fastify 4. The changes look definitely promising (especially looking forward to the type providers which should make our code much cleaner) and I have just upgraded an existing project to Fastify 4.
During upgrading, I encountered the following errors related to the schema which caused me quite some head banging:
schema with key or id "…" already exists
"…" resolves to more than one schema
Steps to Reproduce
While I cannot give our entire schema here, I try to show the (as I think) relevant parts which contribute to this issue. We define our schema using typebox, and after upgrading our dependencies I had to apply these suggestions. Also we use
@fastify/swagger
.I load these through a plugin as follows:
The crucial parts:
File
has more than one$ref
toObjectId
Article
has more than one$ref
toFile
When starting the server, I would either see
schema with key or id "ObjectId" already exists
or"File" resolves to more than one schema
. The behavior was unfortunately not really systematic or deterministic, and depended on the presence or absence of other (seemingly unrelated) routes.After spending several hours, I came up with the following fixes which got the back to running:
In fastify's
schema-controller.js
copy the schemas ingetSchemas
:In
fast-json-stringify
,$refs
seem to get dereferenced to full schema objects, but when occuring several times the duplicate$id
properties lead to the issue described above. My (very dirty) fix was to simply strip out all$id
, but I'm sure that's not the right way to do it:Various code comments and issues (such as this) suggest issues due to mutation of the schema, and I guess my issue is also caused by this.
I would love to provide a runnable example, however I was not really able to reproduce it within a manageable amount of code yet. If there's any more details I can provide, please let me know. On the other hand, I will be happy for any feedback, suggestions, etc.
Expected Behavior
No response
The text was updated successfully, but these errors were encountered: