ComposioHQ/composio · error · ComposioInvalidModifierError

Invalid schema modifier. Not a function.

Error message

Invalid schema modifier. Not a function.

What it means

ComposioInvalidModifierError thrown in getRawComposioTools when a schema modifier is supplied to the tools listing call but is not a function. The SDK validates the modifier before mapping it over the returned tools.

Source

Thrown at ts/packages/core/src/models/Tools.ts:578

    }
    const caseTransformedTools = tools.items.map(tool => this.transformToolCases(tool));

    let modifiedTools = await this.applyDefaultSchemaModifiers(caseTransformedTools);

    // apply local modifiers if they are provided
    if (options?.modifySchema) {
      const modifier = options.modifySchema;
      if (typeof modifier === 'function') {
        const modifiedPromises = modifiedTools.map(tool =>
          modifier({
            toolSlug: tool.slug,
            toolkitSlug: tool.toolkit?.slug ?? 'unknown',
            schema: tool,
          })
        );
        modifiedTools = await Promise.all(modifiedPromises);
      } else {
        throw new ComposioInvalidModifierError('Invalid schema modifier. Not a function.');
      }
    }

    return modifiedTools;
  }

  /**
   * Fetches tools exposed by a tool router session.
   * This includes helper/meta tools plus any tools preloaded into the session.
   * It provides access to the underlying tool data without provider-specific wrapping.
   *
   * @param sessionId {string} The session id to get tools for
   * @param options {SchemaModifierOptions} Optional configuration for tool retrieval
   * @param {TransformToolSchemaModifier} [options.modifySchema] - Function to transform the tool schema
   * @returns {Promise<ToolList>} The list of session tools
   *
   * @example
   * ```typescript

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Ensure the second argument to tools.get is a function ({ toolSlug, toolkitSlug, schema }) => schema
  2. Check typeof modifier where you build the call
  3. Update to the current modifier callback signature

Example fix

// before
composio.tools.get({ toolkits: ['github'] }, { schemaModifier: 'stripDesc' })
// after
composio.tools.get({ toolkits: ['github'] }, ({ schema }) => schema)
Defensive patterns

Strategy: validation

Validate before calling

if (modifier !== undefined && typeof modifier !== 'function') throw new TypeError('modifier must be a function');

Type guard

const isSchemaModifier = (m: unknown): m is TransformToolSchemaModifier => typeof m === 'function';

Try / catch

try { const tools = await composio.tools.get(q, modifier); } catch (e) { if (e instanceof ComposioInvalidModifierError) fixModifier(); else throw e; }

Prevention

When it happens

Trigger: Calling composio.tools.get(query, modifier) or wiring .with({ schemaModifier: ... }) where modifier is null, a string, or an object rather than ({ toolSlug, toolkitSlug, schema }) => schema.

Common situations: Passing modifier config objects from JSON, version mismatch in modifier signature shape, accidental double-wrapping of the modifier.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/e24eb948a75598ec. Report an issue: GitHub.