vercel/ai · error · UnsupportedFunctionalityError
Google schema conversion only supports references to direct
Error message
Google schema conversion only supports references to direct children of root-level $defs or definitions.
What it means
The Google schema converter only resolves `$ref` pointers that target a definition directly under the root-level `$defs` (or `definitions`) object, e.g. `#/$defs/Foo`. Any other reference form (nested paths, anchors, external refs, or refs to sub-properties) cannot be mapped to Google's flat OpenAPI schema and throws UnsupportedFunctionalityError via throwUnsupportedReference.
Source
Thrown at packages/google/src/convert-json-schema-to-openapi-schema.ts:313
const definitionName = decodedDefinitionName.replace(/~[01]/g, match =>
match === '~1' ? '/' : '~',
);
if (
!Object.prototype.hasOwnProperty.call(source.definitions, definitionName)
) {
throwUnsupportedReference(reference);
}
return {
definition: source.definitions[definitionName],
referenceKey: `${source.prefix}${definitionName}`,
};
}
function throwUnsupportedReference(reference: string): never {
throw new UnsupportedFunctionalityError({
functionality: `JSON Schema reference: ${reference}`,
message:
'Google schema conversion only supports references to direct children of root-level $defs or definitions.',
});
}
type EnumValues = NonNullable<JSONSchema7['enum']>;
type EnumType = 'string' | 'number' | 'integer' | 'boolean';
type GoogleEnumSchema = {
type?: JSONSchema7['type'];
enum?: JSONSchema7['enum'];
format?: JSONSchema7['format'];
anyOf?: JSONSchema7['anyOf'];
nullable?: boolean;
};
function addEnumToSchema({
values,View on GitHub (pinned to 69428b1f8b)
Solutions
- Hoist every referenced type to the top-level `$defs`/`definitions` object and reference it as `#/$defs/Name`.
- Inline the referenced sub-schema directly where the ref occurs.
- Run a pre-processing step (e.g. with a $ref bundler like @apidevtools/json-schema-ref-parser) to normalize refs before passing to the model.
Example fix
// before
{ "type": "object", "properties": { "bar": { "$ref": "#/$defs/Foo/properties/bar" } }, "$defs": { "Foo": { "properties": { "bar": { "type": "string" } } } } }
// after
{ "type": "object", "properties": { "bar": { "$ref": "#/$defs/Bar" } }, "$defs": { "Bar": { "type": "string" } } } Defensive patterns
Strategy: validation
Validate before calling
function refsAreDirectChildren(schema) {
const allowed = new Set(Object.keys(schema?.$defs ?? schema?.definitions ?? {}).map(k => `#/$defs/${k}`));
const refs = JSON.stringify(schema).match(/"\$ref"\s*:\s*"([^"]+)"/g) ?? [];
return refs.every(r => { const v = JSON.parse(r.replace(/^"\$ref"\s*:\s*/, '')); return allowed.has(v); });
} Type guard
function hasOnlyRootLevelRefs(schema) {
const keys = new Set(Object.keys(schema.$defs ?? {}));
const walk = (node) => node === null || typeof node !== 'object' ? true
: (typeof node.$ref === 'string' ? /^#\/\$defs\/[\w-]+$/.test(node.$ref) && keys.has(node.$ref.split('/')[2]) : Object.values(node).every(walk));
return walk(schema);
} Try / catch
try {
await generateObject({ model: googleModel, schema });
} catch (e) {
if (e?.message?.includes('direct children of root-level $defs')) {
// normalize refs (inline or hoist) and retry
} else throw e;
} Prevention
- Always place referenced types directly under top-level $defs.
- Use `$ref: '#/$defs/Name'` form only - no nested pointers, anchors, or external refs.
- Bundle/normalize schemas with json-schema-ref-parser before sending to Google.
When it happens
Trigger: A JSON Schema with `$ref: '#/$defs/Foo/properties/bar'`, `$ref: '#/definitions/A/B'`, relative or external `$ref`s, or definitions nested inside other definitions, passed to a Google model for tool/structured output conversion.
Common situations: Hand-edited JSON Schemas with nested refs; schemas generated by tools that emit deep pointer refs; schemas ported from OpenAPI documents with component-internal references.
Related errors
- Google schema conversion does not support recursive JSON Sch
- Google does not support this JSON Schema enum. Enum values m
- Recursive reference detected at ${refs.currentPath.join('/')
- Could not convert regex pattern at ${refs.currentPath.join('
- 'system messages are only supported at the beginning of the
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/267e00dbf886ddf8.
Report an issue: GitHub.