vercel/ai · error · UnsupportedFunctionalityError

tool parameters must be a JSON Schema object with type "obje

Error message

tool parameters must be a JSON Schema object with type "object" for moonshotai (MFJS)

What it means

Moonshot's function calling (MFJS) requires tool parameters to be a JSON Schema object (a record), not a boolean schema. The MFJS normalizer throws UnsupportedFunctionalityError when the ROOT tool parameter schema is a boolean (true/false) or any non-object value, since there is no object to normalize.

Source

Thrown at packages/moonshotai/src/normalize-json-schema-for-mfjs.ts:35

  'if',
  'then',
  'else',
] as const;

/**
 * Normalizes a JSON Schema to the subset Moonshot's MFJS validator accepts:
 * `object` root required, tuple `items` become `prefixItems`, and `type` next
 * to `anyOf` moves into the branches. Everything else passes through. The
 * full original schema is still used for AI SDK result validation.
 */
export function normalizeJsonSchemaForMFJS(schema: unknown): unknown {
  return normalizeDefinition(schema, true);
}

function normalizeDefinition(definition: unknown, isRoot: boolean): unknown {
  if (typeof definition === 'boolean' || !isRecord(definition)) {
    if (isRoot) {
      throw new UnsupportedFunctionalityError({
        functionality:
          'tool parameters must be a JSON Schema object with type "object" for moonshotai (MFJS)',
      });
    }
    return definition;
  }

  if (isRoot && definition.type !== 'object') {
    throw new UnsupportedFunctionalityError({
      functionality:
        'tool parameters must be a JSON Schema object with type "object" for moonshotai (MFJS)',
    });
  }

  const result: Record<string, unknown> = { ...definition };

  // Existing prefixItems stay first (they are positional).
  if (Array.isArray(result.items)) {

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Make the root schema an object: { type: 'object', properties: {}, additionalProperties: false } for a no-arg tool.
  2. Use z.object({}) in Zod so the generated root schema is an object.
  3. Inspect the tool's JSON Schema output and confirm the root is a record with type 'object'.

Example fix

// before
parameters: true
// after
parameters: { type: 'object', properties: {}, additionalProperties: false }
Defensive patterns

Strategy: validation

Validate before calling

function hasObjectRootSchema(tool: { parameters: unknown }): boolean {
  const s = tool.parameters as any;
  return typeof s === 'object' && s !== null && !Array.isArray(s);
}
tools.forEach(t => { if (!hasObjectRootSchema(t)) throw new Error(`tool ${t.name} needs an object root JSON Schema for Moonshot`); });

Type guard

function isRecordSchema(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}

Try / catch

import { UnsupportedFunctionalityError } from '@ai-sdk/provider';
try {
  await generateText({ model: moonshot(id), tools });
} catch (e) {
  if (UnsupportedFunctionalityError.isInstance(e) && e.message.includes('MFJS')) {
    // normalize/replace the offending tool schema
  }
  throw e;
}

Prevention

When it happens

Trigger: Defining a tool whose parameters resolve to a boolean JSON Schema (e.g. z.boolean()-like at top level, or a schema like `true`) and passing it to a Moonshot model, where normalizeJsonSchemaForMFJS is called on the root definition.

Common situations: Creating a no-argument tool with `parameters: true` or a bare boolean schema; using a validation library that emits boolean schemas for empty objects; hand-written JSON Schema with a boolean root.

Related errors


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