paperclipai/paperclip · error

Configuration does not match the plugin's instanceConfigSche

Error message

Configuration does not match the plugin's instanceConfigSchema

What it means

Returned as HTTP 400 by POST /api/plugins/:pluginId/config when configJson fails server-side validation against the plugin's declared instanceConfigSchema (from the plugin manifest). The response includes a fieldErrors array describing exactly which fields are wrong, so CLI/API callers get the same validation the UI performs client-side.

Source

Thrown at server/src/routes/plugins.ts:2340

    }

    // Strip devUiUrl unless the caller is an instance admin. devUiUrl activates
    // a dev-proxy in the static file route that could be abused for SSRF if any
    // board-level user were allowed to set it.
    if (
      "devUiUrl" in body.configJson &&
      !(req.actor.type === "board" && req.actor.isInstanceAdmin)
    ) {
      delete body.configJson.devUiUrl;
    }

    // Validate configJson against the plugin's instanceConfigSchema (if declared).
    // This ensures CLI/API callers get the same validation the UI performs client-side.
    const schema = plugin.manifestJson?.instanceConfigSchema;
    if (schema && Object.keys(schema).length > 0) {
      const validation = validateInstanceConfig(body.configJson, schema);
      if (!validation.valid) {
        res.status(400).json({
          error: "Configuration does not match the plugin's instanceConfigSchema",
          fieldErrors: validation.errors,
        });
        return;
      }
    }

    try {
      const secretRefs = extractSecretRefBindingsFromConfig(body.configJson, schema);
      await validatePluginSecretRefsForCompany(companyId, secretRefs);
      await secretService(db).syncSecretRefsForTarget(
        companyId,
        { targetType: "plugin", targetId: plugin.id },
        secretRefs,
        { replaceAll: true },
      );

      const result = await registry.upsertConfig(plugin.id, companyId, {

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Read the fieldErrors array in the 400 response — it names the exact failing fields and reasons
  2. Fetch the plugin manifest (GET /api/plugins/:pluginId) and inspect instanceConfigSchema to see required fields, types, and enums
  3. Fix the config values to match the schema and resend
  4. If the schema itself is wrong, fix the plugin's manifest instanceConfigSchema and reinstall/register the plugin

Example fix

// before
POST /api/plugins/scheduler/config
{ "companyId": "c1", "configJson": { "region": "eu" } }
// fieldErrors: [ { path: 'port', message: 'Required' } ]
// after
{ "companyId": "c1", "configJson": { "region": "eu", "port": 8080 } }
Defensive patterns

Strategy: validation

Validate before calling

const plugin = await (await fetch(`/api/plugins/${pluginId}`)).json();
const schema = plugin.manifestJson?.instanceConfigSchema;
if (schema) {
  for (const key of Object.keys(schema)) {
    if (schema[key]?.required && configJson[key] === undefined) {
      throw new Error(`Missing required config field: ${key}`);
    }
  }
}

Try / catch

try { await savePluginConfig(pluginId, companyId, configJson); } catch (e) { if (e.status === 400 && e.body.fieldErrors) showFieldErrors(e.body.fieldErrors); else throw e; }

Prevention

When it happens

Trigger: Sending configJson that misses a required field defined in the plugin's instanceConfigSchema, supplies a wrong primitive type (string where number is declared), includes an unknown/extra property when the schema does not allow it, or omits nested required keys.

Common situations: Plugin upgraded its manifest and now requires new fields; the caller copied an example config from an older plugin version; a typo in a field name (api_key vs apiKey) makes it look like a missing required field.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18). Data as JSON: /api/errors/c8dccbe738e4071e. Report an issue: GitHub.