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
- Reinstall/upgrade the Telegram adapter package so the full parser surface (extractAttachments, createAttachment, parseTelegramMessage) is present.
- Check the adapter version against the runtime's expectations; pin a compatible version.
- If using a custom adapter, implement all three parser methods with the expected signatures.
- 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
- Pin the adapter package version; reinstall on version drift.
- Add a startup assertion that the parser surface is complete.
- Avoid custom adapter forks that omit parser methods.
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
- ACPX sidecar runtime context must be pre-materialized
- Adapter declares unsupported UI parser contract version —…
- CHAT_PROVIDER_PRETRANSPORT_REJECTED
- createServerAdapter() from
- device-login credential promotion rejected: the promotion…
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)