Hmbown/CodeWhale · error · Error
Lark SDK client does not expose im message create API
Error message
Lark SDK client does not expose im message create API
What it means
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.
Source
Thrown at integrations/feishu-bridge/src/index.mjs:554
}
async function sendText(chatId, text) {
// Try reply API first — keeps bot responses inside the same Feishu
// thread/topic instead of spawning new standalone topics.
// / 优先使用 reply API,确保 bot 回复留在话题群的同一条话题内。
const state = await threadStore.getChat(chatId);
const replyToMessageId = state?.replyToMessageId || null;
const replyMessage =
replyToMessageId
? client.im?.v1?.message?.reply?.bind(client.im.v1.message) ||
client.im?.message?.reply?.bind(client.im.message)
: null;
const createMessage =
client.im?.v1?.message?.create?.bind(client.im.v1.message) ||
client.im?.message?.create?.bind(client.im.message);
if (!createMessage) {
throw new Error("Lark SDK client does not expose im message create API");
}
let canReply = Boolean(replyMessage);
for (const chunk of splitMessage(text, config.maxReplyChars)) {
const body = {
msg_type: "text",
content: JSON.stringify({ text: chunk })
};
if (canReply) {
try {
await replyMessage({
path: { message_id: replyToMessageId },
data: body
});
continue;
} catch (error) {
canReply = false;
console.warn("Feishu reply API failed; falling back to message create", error);View on GitHub (pinned to 8880682c63)
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
Example fix
// before - capability discovered only when a message must be sent
const createMessage = client.im?.v1?.message?.create?.bind(client.im.v1.message) ||
client.im?.message?.create?.bind(client.im.message);
if (!createMessage) throw new Error('Lark SDK client does not expose im message create API');
// after - fail fast at startup with the fix in the message
const createMessage = client.im?.v1?.message?.create?.bind(client.im.v1.message) ||
client.im?.message?.create?.bind(client.im.message);
if (!createMessage) {
throw new Error('Unsupported @larksuiteoapi/node-sdk: upgrade to a version exposing im.v1.message.create');
} Defensive patterns
Strategy: type-guard
Validate before calling
const createMessage =
client.im?.v1?.message?.create?.bind(client.im.v1.message) ||
client.im?.message?.create?.bind(client.im.message);
if (!createMessage) {
throw new Error('Unsupported @larksuiteoapi/node-sdk: upgrade to a version exposing im.v1.message.create');
} Type guard
function larkCanSendMessage(client) {
return typeof (client.im?.v1?.message?.create || client.im?.message?.create) === 'function';
}
// usage: if (!larkCanSendMessage(client)) failFastAtStartup(); Prevention
- 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
When it happens
Trigger: 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.
Common situations: package-lock pinning an old @larksuiteoapi/node-sdk; wrapper clients stripping namespaces; breaking SDK majors.
Related errors
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/8f2e9d4293d5d13a.
Report an issue: GitHub.