Problem
Running toolcraft-openapi-generate against an OpenAPI 3.1 / JSON Schema 2020-12 spec fails on nullable fields:
$ npm run generate
> toolcraft-openapi-generate --input https://www.i.quora.com/api/internal_agent/openapi.json --output src/generated --lock openapi.lock
Operation "patch_bot" uses unsupported requestBody.properties.display_name. JSON Schema composition keyword "anyOf" is not supported in v1.
Root cause
The spec's BotPatchRequest schema expresses nullable fields using the standard OpenAPI 3.1 syntax — anyOf with a null type variant:
{
"BotPatchRequest": {
"type": "object",
"properties": {
"display_name": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
],
"title": "Display Name"
},
"description": { "anyOf": [{ "type": "string" }, { "type": "null" }] },
"introduction": { "anyOf": [{ "type": "string" }, { "type": "null" }] },
"allow_related_bot_recommendations": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] },
"picture_url": { "anyOf": [{ "type": "string", "format": "uri", "minLength": 1, "maxLength": 2083 }, { "type": "null" }] }
}
}
}
This is the standard OpenAPI 3.1 way to express T | null (it replaces OpenAPI 3.0's nullable: true). Pydantic/FastAPI emits this shape by default for Optional[T] fields.
Every nullable field in the schema follows the same pattern, so even if display_name were special-cased, the next field would fail the same way.
Suggested fix
Recognize the anyOf: [T, {type: null}] (and the two-element variant in either order) shape as nullable T and lower it to whatever representation the generator already uses for nullables. Full anyOf support would be ideal, but the nullable case alone unblocks this spec.
Repro
- Repo:
poe-platform/poe-internal-agent-tools
- Command:
npm run generate
- Input:
https://www.i.quora.com/api/internal_agent/openapi.json
Problem
Running
toolcraft-openapi-generateagainst an OpenAPI 3.1 / JSON Schema 2020-12 spec fails on nullable fields:Root cause
The spec's
BotPatchRequestschema expresses nullable fields using the standard OpenAPI 3.1 syntax —anyOfwith anulltype variant:{ "BotPatchRequest": { "type": "object", "properties": { "display_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Display Name" }, "description": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "introduction": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "allow_related_bot_recommendations": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] }, "picture_url": { "anyOf": [{ "type": "string", "format": "uri", "minLength": 1, "maxLength": 2083 }, { "type": "null" }] } } } }This is the standard OpenAPI 3.1 way to express
T | null(it replaces OpenAPI 3.0'snullable: true). Pydantic/FastAPI emits this shape by default forOptional[T]fields.Every nullable field in the schema follows the same pattern, so even if
display_namewere special-cased, the next field would fail the same way.Suggested fix
Recognize the
anyOf: [T, {type: null}](and the two-element variant in either order) shape as nullableTand lower it to whatever representation the generator already uses for nullables. FullanyOfsupport would be ideal, but the nullable case alone unblocks this spec.Repro
poe-platform/poe-internal-agent-toolsnpm run generatehttps://www.i.quora.com/api/internal_agent/openapi.json