{"record":{"id":"8f2e9d4293d5d13a","repo":"Hmbown/CodeWhale","slug":"lark-sdk-client-does-not-expose-im-message-create","errorCode":null,"errorMessage":"Lark SDK client does not expose im message create API","messagePattern":"Lark SDK client does not expose im message create API","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/feishu-bridge/src/index.mjs","lineNumber":554,"sourceCode":"}\n\nasync function sendText(chatId, text) {\n  // Try reply API first — keeps bot responses inside the same Feishu\n  // thread/topic instead of spawning new standalone topics.\n  // / 优先使用 reply API，确保 bot 回复留在话题群的同一条话题内。\n  const state = await threadStore.getChat(chatId);\n  const replyToMessageId = state?.replyToMessageId || null;\n\n  const replyMessage =\n    replyToMessageId\n      ? client.im?.v1?.message?.reply?.bind(client.im.v1.message) ||\n        client.im?.message?.reply?.bind(client.im.message)\n      : null;\n  const createMessage =\n    client.im?.v1?.message?.create?.bind(client.im.v1.message) ||\n    client.im?.message?.create?.bind(client.im.message);\n  if (!createMessage) {\n    throw new Error(\"Lark SDK client does not expose im message create API\");\n  }\n\n  let canReply = Boolean(replyMessage);\n  for (const chunk of splitMessage(text, config.maxReplyChars)) {\n    const body = {\n      msg_type: \"text\",\n      content: JSON.stringify({ text: chunk })\n    };\n    if (canReply) {\n      try {\n        await replyMessage({\n          path: { message_id: replyToMessageId },\n          data: body\n        });\n        continue;\n      } catch (error) {\n        canReply = false;\n        console.warn(\"Feishu reply API failed; falling back to message create\", error);","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/integrations/feishu-bridge/src/index.mjs#L536-L572","documentation":"sendReply() resolves the Lark message-create entry point through both the v1 layout (client.im.v1.message.create) and the legacy flat layout (client.im.message.create). If neither exists, the installed @larksuiteoapi/node-sdk is too old or does not expose the IM API, and the bridge refuses to send rather than failing obscurely later.","triggerScenarios":"Running the bridge with an SDK version predating client.im.v1; a custom/mock client in tests that omits the im namespace; an SDK refactor that moved the message API.","commonSituations":"package-lock pinning an old @larksuiteoapi/node-sdk; wrapper clients stripping namespaces; breaking SDK majors.","solutions":["Upgrade the SDK: npm install @larksuiteoapi/node-sdk@latest in integrations/feishu-bridge","Log Object.keys(client.im || {}) once to see which layout the SDK provides","If pinned intentionally, write a small adapter exposing the expected shape instead of removing the check"],"exampleFix":"// before - capability discovered only when a message must be sent\nconst createMessage = client.im?.v1?.message?.create?.bind(client.im.v1.message) ||\n  client.im?.message?.create?.bind(client.im.message);\nif (!createMessage) throw new Error('Lark SDK client does not expose im message create API');\n\n// after - fail fast at startup with the fix in the message\nconst createMessage = client.im?.v1?.message?.create?.bind(client.im.v1.message) ||\n  client.im?.message?.create?.bind(client.im.message);\nif (!createMessage) {\n  throw new Error('Unsupported @larksuiteoapi/node-sdk: upgrade to a version exposing im.v1.message.create');\n}","handlingStrategy":"type-guard","validationCode":"const createMessage =\n  client.im?.v1?.message?.create?.bind(client.im.v1.message) ||\n  client.im?.message?.create?.bind(client.im.message);\nif (!createMessage) {\n  throw new Error('Unsupported @larksuiteoapi/node-sdk: upgrade to a version exposing im.v1.message.create');\n}","typeGuard":"function larkCanSendMessage(client) {\n  return typeof (client.im?.v1?.message?.create || client.im?.message?.create) === 'function';\n}\n// usage: if (!larkCanSendMessage(client)) failFastAtStartup();","tryCatchPattern":null,"preventionTips":["Check SDK capabilities at startup, not at first send","Upgrade @larksuiteoapi/node-sdk deliberately and re-run bridge smoke tests","Pin the SDK to a tested version range in package.json"],"tags":["feishu","lark-sdk","dependency","version-mismatch"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}