paperclipai/paperclip · error

Telegram attachment parser contract is unavailable

Error message

Telegram attachment parser contract is unavailable

What it means

The Telegram attachment path relies on the adapter exposing three functions: extractAttachments, createAttachment, and parseTelegramMessage. When the loaded parser object is missing any of these methods, the runtime throws this error because it cannot honor the Telegram attachment parser contract.

Solutions

  1. Reinstall/upgrade the Telegram adapter package so the full parser surface (extractAttachments, createAttachment, parseTelegramMessage) is present.
  2. Check the adapter version against the runtime's expectations; pin a compatible version.
  3. If using a custom adapter, implement all three parser methods with the expected signatures.
  4. Log the parser object at startup and assert the three methods exist as part of a smoke test.

Example fix

// before
const parser = require("telegram-adapter-lite").parser; // missing parseTelegramMessage
// after
const parser = require("@paperclipai/telegram-adapter").parser;
for (const m of ["extractAttachments", "createAttachment", "parseTelegramMessage"] as const) {
  if (typeof parser[m] !== "function") throw new Error(`parser missing ${m}`);
}
Defensive patterns

Strategy: type-guard

Validate before calling

function hasTelegramParser(p: unknown): p is { extractAttachments: Function; createAttachment: Function; parseTelegramMessage: Function } {
  return typeof p === "object" && p !== null &&
    ["extractAttachments", "createAttachment", "parseTelegramMessage"].every(
      (m) => typeof (p as any)[m] === "function");
}

Type guard

function hasTelegramParser(p: unknown): p is { extractAttachments: Function; createAttachment: Function; parseTelegramMessage: Function } {
  return typeof p === "object" && p !== null &&
    typeof (p as any).extractAttachments === "function" &&
    typeof (p as any).createAttachment === "function" &&
    typeof (p as any).parseTelegramMessage === "function";
}

Try / catch

try {
  await telegramRuntime.start();
} catch (err) {
  if (/parser contract/.test(String(err?.message))) {
    logger.error("Telegram adapter missing attachment parser; reinstall/upgrade the adapter package");
  }
  throw err;
}

Prevention

When it happens

Trigger: Initializing/using the Telegram runtime where the adapter object's parser lacks extractAttachments, createAttachment, or parseTelegramMessage as functions.

Common situations: Downgraded or partially installed adapter package; adapter version drift where parser methods were renamed/removed; custom adapter builds missing the attachment parser module; dependency resolution pulling a stub implementation.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-10). Data as JSON: /api/errors/0783f15e318f18bb. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/chat-sdk-runtime.ts:1512

      const parser = adapter as unknown as {
        extractAttachments(raw: TelegramRawMessage): Attachment[];
        parseTelegramMessage(
          raw: TelegramRawMessage,
          threadId: string,
          content?: { text: string; formatted: Message["formatted"] },
        ): Message;
        createAttachment(
          type: Attachment["type"],
          fileId: string,
          metadata: Record<string, unknown>,
        ): Attachment;
      };
      if (
        typeof parser.extractAttachments !== "function" ||
        typeof parser.createAttachment !== "function" ||
        typeof parser.parseTelegramMessage !== "function"
      ) {
        throw new Error("Telegram attachment parser contract is unavailable");
      }
      const extractAttachments = parser.extractAttachments.bind(adapter);
      const create = (
        type: Attachment["type"],
        fileId: string,
        metadata: Record<string, unknown>,
      ) => parser.createAttachment(type, fileId, metadata);
      parser.extractAttachments = (raw) =>
        normalizeTelegramRichMessage(raw, create)?.attachments ??
        normalizeTelegramMediaAttachments(
          raw,
          normalizeTelegramVideoNoteAttachments(raw, extractAttachments(raw)),
          create,
        );
      const parseTelegramMessage = parser.parseTelegramMessage.bind(adapter);
      parser.parseTelegramMessage = (raw, threadId, content) => {
        const rich = normalizeTelegramRichMessage(raw, create);
        if (!rich) return parseTelegramMessage(raw, threadId, content);

View on GitHub (pinned to 3f1d897a7c)