KINTO Tech Blog
Slack

Troubleshooting Slack CLI: Resolving block_id Conflicts When Sending Messages

Cover Image for 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:

  1. A form input contains a value in rich_text format.
  2. The value is stored in the DataStore as rich_text.
  3. Multiple rich_text entries are retrieved from the DataStore, concatenated, and formatted.
  4. A block is created and sent using postMessage

Process Flow

However, the process failed with the error: parameter_validation_failed.

Error

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.

https://api.slack.com/reference/block-kit/blocks

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.

Error 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!

Facebook

関連記事 | Related Posts

We are hiring!

【iOSエンジニア】モバイルアプリ開発G/東京

モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。

【プロジェクトマネージャー】モバイルアプリ開発G/大阪

モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。

イベント情報

P3NFEST Bug Bounty 2025 Winter 【KINTOテクノロジーズ協賛】