-
-
Notifications
You must be signed in to change notification settings - Fork 208
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
Recursive validation schema compiles but fails at runtime #648
Comments
Ajv is good - the |
I get the exact same error with this version of the code, where import Fastify from "fastify";
const schema = {
$schema: "http://json-schema.org/draft-07/schema#",
title: "Schema Response",
type: "object",
required: [],
properties: {
types: {
description: "A list of types.",
type: "array",
items: {
$ref: "#/definitions/Type",
},
},
},
definitions: {
Type: {
title: "Type",
description: "Types track the valid representations of values as JSON",
oneOf: [
{
description: "A named type",
type: "object",
required: ["name", "type"],
properties: {
name: {
description:
"The name can refer to a primitive type or a scalar type",
type: "string",
},
type: {
type: "string",
enum: ["named"],
},
},
},
{
description: "A nullable type",
type: "object",
required: ["type", "underlying_type"],
properties: {
type: {
type: "string",
enum: ["nullable"],
},
underlying_type: {
description: "The type of the non-null inhabitants of this type",
allOf: [
{
$ref: "#/definitions/Type",
},
],
},
},
},
],
},
},
};
const data = {
types: [
{
type: "named",
name: "Int",
},
{
type: "nullable",
underlying_type: {
type: "named",
name: "String",
},
},
],
};
async function start_server() {
const server = Fastify({
logger: true,
});
server.get(
"/",
{
schema: {
response: {
200: schema,
},
},
},
() => {
return data;
}
);
try {
await server.listen({ port: 3030 });
} catch (error) {
server.log.error(error);
process.exit(1);
}
}
start_server(); The original schema that gave me issues did not have I also want to note that I found ways around this that suggest this is a bug:
|
Can confirm that using server.setSerializerCompiler(
({ schema, method, url, httpStatus, contentType }) => {
return (data) => JSON.stringify(data);
}
); Should I close this issue and re-open on the fast-json-stringify repo instead? |
@BenoitRanque Hi, I see where is the problem. Unfortunately you have a killing combo of recursive allOf and anyOf. It's a hard one. I don't have time to solve it right now, but I have a workaround for you. Why don't you drop an unnecessary Before: const schema = {
underlying_type: {
description: 'The type of the non-null inhabitants of this type',
allOf: [
{
$ref: '#/definitions/Type'
}
]
}
} After: const schema = {
underlying_type: {
description: 'The type of the non-null inhabitants of this type',
$ref: '#/definitions/Type'
}
} |
Unfortunately, I cannot modify this schema easily, as this is generated automatically and is in practice much more complex. I did manage to narrow down the use-case that results in this particular combination showing up: #[derive(Serialize, Deserialize, JsonSchema)]
struct ObjectField {
/// The type of this field
#[serde(rename = "type")]
r#type: Type,
}
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
enum Type {
Nullable { underlying_type: Box<Type> },
Named { name: String },
}
#[test]
fn test() {
println!(
"{}",
serde_json::to_string_pretty(&schema_for!(ObjectField)).unwrap()
);
}
} It turns out, what triggers this is specifically this documentation comment:
Somehow the generator decides that the presence of this comment justifies the I don't know if that should be considered a bug. Either way, we are not currently blocked on this, and it's possible we won't be using this code at all, but I did want to follow up. Thanks for looking into it! |
Prerequisites
Fastify version
4.23.2
Plugin version
No response
Node.js version
18.12.1
Operating system
Windows
Operating system version (i.e. 20.04, 11.3, 10)
11
Description
The following error is thrown when validating a response using a response schema, when trying to return a response:
This is unexpected: it's my understanding that schemas should be validated on server startup.
The error also does not throw if the response does not include the problematic parts of the schema.
This is most likely an AJV bug, but I was not able to reproduce it trivially. I would appreciate help with isolating the Fastify-AJV interaction to reproduce this without the Fastify server at all.
Steps to Reproduce
Full sample code:
Fastify version: 4.23.2
To reproduce the error, run the server, and perform a GET request against it.
Expected Behavior
The response should be validated successfully, or it should fail to validate, but not fail to resolve the validation schema, except on server startup.
Note, the following using only AJV does not error:
I strongly suspect this is an AJV issue, but as the above did not repro the problem I would appreciate any help in isolating the issue.
Workarounds
I've observed two ways to avoid this issue:
$recursiveRef
instead of$ref
. I don't believe this is the correct use case for$recursiveRef
, but it does make the problem go away$id
on the root, then qualify$refs
with the id before the#
Possibly related issues
Using discriminator in a definition causes failure to compile if oneOf contains a reference fastify/fastify#1899
Is it possible to create a recursive schema definition? fastify/fastify#659
The text was updated successfully, but these errors were encountered: