paperclipai/paperclip · warning

Adapter declares unsupported UI parser contract version — sk

Error message

Adapter declares unsupported UI parser contract version — skipping UI parser

What it means

When loading a third-party adapter package, the plugin-loader reads package.json exports["./ui-parser"] plus the pkg.paperclip.adapterUiParser contract version. If the declared major does not equal the server's SUPPORTED_PARSER_CONTRACT (currently "1"), the UI parser is skipped — the adapter itself still loads, but its UI parsing falls back to the default behavior.

Source

Thrown at server/src/adapters/plugin-loader.ts:101

const SUPPORTED_PARSER_CONTRACT = "1";

function extractUiParserSource(
  packageDir: string,
  packageName: string,
): string | undefined {
  const pkgJsonPath = path.join(packageDir, "package.json");
  const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));

  if (!pkg.exports || typeof pkg.exports !== "object" || !pkg.exports["./ui-parser"]) {
    return undefined;
  }

  const contractVersion = pkg.paperclip?.adapterUiParser;
  if (contractVersion) {
    const major = contractVersion.split(".")[0];
    if (major !== SUPPORTED_PARSER_CONTRACT) {
      logger.warn(
        { packageName, contractVersion, supported: `${SUPPORTED_PARSER_CONTRACT}.x` },
        "Adapter declares unsupported UI parser contract version — skipping UI parser",
      );
      return undefined;
    }
  } else {
    logger.info(
      { packageName },
      "Adapter has ./ui-parser export but no paperclip.adapterUiParser version — loading anyway (future versions may require it)",
    );
  }

  const uiParserExp = pkg.exports["./ui-parser"];
  const uiParserFile = typeof uiParserExp === "string"
    ? uiParserExp
    : (uiParserExp.import ?? uiParserExp.default);
  const uiParserPath = path.resolve(packageDir, uiParserFile);

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Align versions: upgrade paperclip-server (to get the new contract) or pin the adapter to a release built for contract major 1.
  2. Inspect the adapter's package.json paperclip.adapterUiParser and compare against the server's supported major.
  3. If you maintain the adapter, rebuild/republish against the contract version the target server supports.
  4. Accept degraded UI parsing if the adapter's core functionality is unaffected.

Example fix

// adapter package.json — before
"paperclip": { "adapterUiParser": "2.0" }

// after (targeting a contract-1 server)
"paperclip": { "adapterUiParser": "1.0" }
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_MAJOR = '1'; // keep in sync with the server's parser contract
const pkg = JSON.parse(fs.readFileSync(path.join(adapterDir, 'package.json'), 'utf-8'));
const declared = pkg.paperclip?.adapterUiParser;
if (declared && declared.split('.')[0] !== SUPPORTED_MAJOR) {
  throw new Error(`Adapter ${pkg.name} targets UI parser contract ${declared}; server supports ${SUPPORTED_MAJOR}.x`);
}

Prevention

When it happens

Trigger: An adapter package declares paperclip.adapterUiParser like "2.0" (built against a newer contract) or "0.x" while the running paperclip-server supports major "1"; the loader logs this and returns undefined for the parser.

Common situations: Upgrading an adapter package without upgrading paperclip-server (or the reverse); community adapters lagging a contract bump; mixed lockfile versions in a monorepo.

Related errors


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