vercel/ai · error · UnsupportedFunctionalityError

Google does not support this JSON Schema enum. Enum values m

Error message

Google does not support this JSON Schema enum. Enum values must share one supported primitive type and match the schema type.

What it means

Google's function-calling schema format requires enum values to be a homogeneous list of one supported primitive type (string, number, integer, boolean) that also matches the declared schema `type`. Mixed-type enums (e.g. ['red', 1, true]) or enums whose values don't match `type` cannot be represented and throw this error in addEnumToSchema.

Source

Thrown at packages/google/src/convert-json-schema-to-openapi-schema.ts:364

  if (values.length > 0 && values.every(value => value === null)) {
    const typeAllowsNull =
      type === undefined ||
      type === 'null' ||
      (Array.isArray(type) && type.includes('null'));

    if (typeAllowsNull) {
      result.type = 'null';
      if (Array.isArray(type)) {
        delete result.anyOf;
      }
      return;
    }
  }

  const enumType = getEnumType({ values: enumValues, type });

  if (enumType === undefined) {
    throw new UnsupportedFunctionalityError({
      functionality: 'JSON Schema enum with mixed or unsupported values',
      message:
        'Google does not support this JSON Schema enum. Enum values must share one supported primitive type and match the schema type.',
    });
  }

  result.type = enumType;

  // The earlier type-array conversion created anyOf. The enum gives us one
  // concrete value type, so store that type directly.
  if (Array.isArray(type)) {
    delete result.anyOf;
  }

  if (nullable) {
    result.nullable = true;
  }

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Make all enum values the same primitive type (e.g. all strings: '1', '2' instead of 1, 2).
  2. If the declared `type` exists, ensure the enum values match it (numeric enum -> type 'number'/'integer').
  3. Replace the enum with a plain typed field plus a description listing allowed values.

Example fix

// before
z.union([z.literal('active'), z.literal(1)])
// after
z.enum(['active', 'one']) // or all numeric literals
Defensive patterns

Strategy: validation

Validate before calling

function enumIsHomogeneous(schema) {
  if (!Array.isArray(schema.enum)) return true;
  const types = new Set(schema.enum.map(v => v === null ? 'null' : Array.isArray(v) ? 'array' : typeof v));
  if (types.size > 1) return false;
  if (schema.type) return [...types].every(t => t === schema.type || (schema.type === 'integer' && t === 'number'));
  return true;
}

Type guard

function isGoogleSafeEnum(schema) {
  if (!Array.isArray(schema.enum) || schema.enum.length === 0) return true;
  const first = typeof schema.enum[0];
  return ['string', 'number', 'boolean'].includes(first) && schema.enum.every(v => typeof v === first);
}

Try / catch

try {
  await generateText({ model: googleModel, tools });
} catch (e) {
  if (e?.message?.includes('JSON Schema enum')) {
    // coerce enum to uniform strings and retry
  } else throw e;
}

Prevention

When it happens

Trigger: A zod schema like z.enum(['a', 1]) (mixed types), z.union([z.literal('x'), z.literal(2)]), or a JSON Schema enum whose values mix strings/numbers/objects/arrays/null, converted for a Google model's tool parameters.

Common situations: Ports of tool schemas from OpenAI/Anthropic (which tolerate heterogeneous enums); legacy APIs with status codes mixing numbers and strings; schemas hand-written with null mixed into enum lists.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/8ad53f977217baa3. Report an issue: GitHub.