FlowiseAI/Flowise · warning · Error
Message is not pinned in this chat
Error message
Message is not pinned in this chat
What it means
Thrown by UnpinChatMessage after it successfully lists pinned messages at GET /chats/{chatId}/pinnedMessages but finds no record whose message.id matches the supplied messageId. This is a conditional runtime error indicating the message is not currently pinned, so there is nothing to unpin.
Source
Thrown at packages/components/nodes/tools/MicrosoftTeams/core.ts:993
super({ ...toolInput, accessToken: args.accessToken, defaultParams: args.defaultParams })
}
protected async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const { chatId, messageId } = params
if (!chatId || !messageId) {
throw new Error('Both Chat ID and Message ID are required')
}
try {
// First get the pinned messages to find the pinned message ID
const pinnedEndpoint = `/chats/${chatId}/pinnedMessages`
const pinnedResult = await this.makeTeamsRequest(pinnedEndpoint)
const pinnedMessage = pinnedResult.value?.find((pm: any) => pm.message?.id === messageId)
if (!pinnedMessage) {
throw new Error('Message is not pinned in this chat')
}
const endpoint = `/chats/${chatId}/pinnedMessages/${pinnedMessage.id}`
await this.makeTeamsRequest(endpoint, 'DELETE')
return this.formatResponse(
{
success: true,
message: 'Message unpinned successfully'
},
params
)
} catch (error) {
return this.formatResponse(`Error unpinning message: ${error}`, params)
}
}
}
View on GitHub (pinned to abe4a8601a)
Solutions
- Treat this as benign if the goal is to ensure the message is not pinned (idempotent).
- Call a list-pinned-messages tool first to confirm the message is pinned before unpinning.
- Verify the messageId belongs to the given chatId.
- Refresh the pinned list before retrying to avoid stale state.
Example fix
// before: blind unpin
await unpinTool._call({ chatId, messageId })
// after: verify pinned first
const pinned = JSON.parse(await listPinnedTool._call({ chatId }))
const isPinned = pinned.some(pm => pm.message?.id === messageId)
if (isPinned) await unpinTool._call({ chatId, messageId }) Defensive patterns
Strategy: validation
Validate before calling
async function isMessagePinned(listPinnedTool: any, chatId: string, messageId: string): Promise<boolean> {
const res = await listPinnedTool.call({ chatId })
const arr = JSON.parse(res)
const list = Array.isArray(arr) ? arr : arr.value
return Array.isArray(list) && list.some((pm: any) => pm.message?.id === messageId)
} Type guard
null
Try / catch
try {
await unpinTool.call({ chatId, messageId })
} catch (e) {
if (e instanceof Error && e.message === 'Message is not pinned in this chat') {
// already unpinned: treat as success (idempotent)
} else throw e
} Prevention
- Treat unpin as idempotent.
- Verify the messageId belongs to the given chatId.
- Refresh the pinned list before retrying.
When it happens
Trigger: Calling UnpinChatMessage for a message that was never pinned or was already unpinned; messageId refers to a message in a different chat; the pinned list is stale because another client unpinned it.
Common situations: Idempotent retry of an unpin that already succeeded; agent confused about which message was pinned; cross-chat messageId mismatch.
Related errors
- User is not a member of this chat
- Both Chat ID and User ID are required
- Both Chat ID and Message ID are required
- Chat or Channel ID is required
- Chat/Channel ID and Message ID are required
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/45b4e8c22d924627.
Report an issue: GitHub.