Troubleshooting Slack CLI: Resolving block_id Conflicts When Sending Messages

This article is the entry for Day 5 of the KINTO Technologies Advent Calendar 2024
Hi, I'm Ryomm, also known as "The Phantom Bot Craftsman", and I develop the My Route iOS app at KINTO Technologies. Here’s a quick tip from Manabyi.
Although this article focuses on Slack CLI, it’s important to note that it operates using the Slack API internally. Consequently, the same issue can arise when interacting directly with the Slack API.
Background
While using Slack CLI, I encountered an issue where Block Kit messages failed to send under the following conditions:
- A form input contains a value in rich_text format.
- The value is stored in the DataStore as rich_text.
- Multiple rich_text entries are retrieved from the DataStore, concatenated, and formatted.
- A block is created and sent using
postMessage
However, the process failed with the error: parameter_validation_failed
.
Cause
The error was triggered due to an invalid parameter during message transmission. Upon investigation, I found that the block_id
values were duplicated in the block I was trying to send, as shown below.
[
{
"type": "rich_text",
"block_id": "xdrwH", // <- this
"elements": [
/* ... */
]
}, {
"type": "rich_text",
"block_id": "xdrwH", // <- this
"elements": [
/* ... */
]
}
]
It appears that the message can't be sent to Slack because the block_id
in the message you're trying to send conflicts with an existing one.
block_id
block_id
is a unique identifier for a block. The official documentation explains it as follows:
A unique identifier for a block. If not specified, a block_id will be generated. You can use this block_id when you receive an interaction payload to identify the source of the action. Maximum length for this field is 255 characters. block_id should be unique for each message and each iteration of a message. If a message is updated, use a new block_id.
If you create a block without specifying a block_id
, a block_id
will be automatically generated. This is mainly used for interactive elements, such as identifying which block a button was pressed on during user interactions.
A block_id must be unique within a single message or across a sequence of repeated messages (i.e., a series of bidirectional interactions). Additionally, when a message is updated, a new block_id
must be used.
In this case, the block_id
contained in the received rich_text was automatically generated.
Additionally, since the rich_text input was received as separate messages during the initial process, block_id
duplication was likely to occur. As a result, this issue occurred due to a conflict with the auto-generatedblock_id
Here is a Haiku for this occasion.
Thought it was safe, Auto-generated failed me, Block_id conflict
This haiku reflects my shock and disbelief—I had believed that an auto-generated block_id, like a UUID, wouldn’t easily collide, yet it did.
This is just my speculation, but it seems that Slack generates block_id
based on the block’s content. To test this, I inputted the exact same text multiple times, and each time, the same block_id
was generated.
Type hoge in rich_text
Each time, the generated block_id was RlmLN
.
{
"type": "rich_text",
"block_id": "RlmLN",
"elements": [
{
"type": "rich_text_section",
"elements": [
{
"text": "hoge",
"type": "text"
}
]
}
]
}
Therefore, if there’s a possibility of identical inputs, it’s safe to assume that block_id
collisions are just as likely.
Solution
When merging multiple blocks into a single message for Slack, each block_id within the message must be unique.
The simplest solution is to delete the block_id
, especially if interactivity isn’t needed. Since Slack will automatically generate a new block_id
if one isn’t specified, you can remove it and proceed with sending the message.
Here’s part of the formatting method: The delete operator is used to remove the block_id property from the object.
// The items obtained from client.apps.datastore.query are included in the event argument
// Reference: https://api.slack.com/methods/apps.datastore.query#examples
function eventMessage(event) {
// ...
event.description.forEach((description) => {
if (description.block_id) {
delete description.block_id // 🐈❗️
}
message.push(description)
})
// ...
}
Now, you can send messages without worrying about block_id
conflicts!
However, removing block_id
from the object is not the best approach if you need interactive functionality. In that case, it’s best to generate and assign a block_id
on the application side before sending the message.
Conclusion
This was a story about block_id
conflicts preventing messages from being sent!
関連記事 | Related Posts
![Cover Image for [Michi-no-eki series of learning] We created a super exciting Slack bot "Manabyi"](/assets/blog/authors/ryomm/2024-12-04/thumbnail.png)
[Michi-no-eki series of learning] We created a super exciting Slack bot "Manabyi"

【学びの道の駅シリーズ】超エキサイティングなSlack bot「まなびぃ」つくった

Rapid Verification: Generative AI-Powered Chat API for MVP Development

A story about JavaScript error detection in browser

Advent Calendar 2023 Announcement

Learning Roadside Station: We Popped into the iOS Team's Study Session
We are hiring!
【iOSエンジニア】モバイルアプリ開発G/東京
モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。
【プロジェクトマネージャー】モバイルアプリ開発G/大阪
モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。