Hi All! Sharing some findings after I spent some time building a simple workflow that comprises an AI Agent sending an email (Gmail node) and that includes HITL with Slack.
The flow is quite simple (theoretical/demo use case):
- Input contains a user’s review of a product, normally with a negative sentiment.
- AI Agent node has access to the Gmail node to send the author an apologetic email. Its prompt is something along the lines of “here is a bad review, address their concerns”.
- HITL is done with Slack, where the message sent to Slack for approval contains the generated email HTML body.
Now, the issue is with the Slack HITL node, which I found threw an invalid_blocks error seemingly “at random”.
Turns out it wasn’t quite random, but the error occurred when the email message to be reviewed, was too long. I did not find an answer in the Slack API documentation, but this Stack Overflow post prompted me to confirm this through trial and error (slicing the message to fewer characters).
I thought it was worth raising here; the error from the Slack node kept me searching for a little while, and perhaps an improvement is possible there? I guess the regular Slack node might also throw this error when trying to send a block that is too long, but it is at least more configurable.
Any thoughts on how this may be made less obscure, or a less likely cause for failure?
Relevant nodes from the workflow I was building:
Good find — the individual text fields inside Slack blocks are capped at 3000 chars, and hitting that limit gives the generic invalid_blocks error which isn’t exactly helpful to debug. Truncating the message content before it hits the node is the right workaround. A nice addition is to append ... and something like (truncated for Slack display) so HITL reviewers know they’re not seeing the full message.
1 Like
Good catch, and worth documenting the limits more precisely for others who hit this:
- Slack block text fields: 3000 chars max
- Total blocks payload per message: 50 blocks max
- Section block text (mrkdwn): 3000 chars
- Context block elements: 10 elements max
For HITL workflows specifically, a Code node before the Slack node to sanitize content is the cleanest fix. Here’s the pattern:
const MAX_CHARS = 2900; // Leave buffer below 3000
const rawContent = $json.email_body || '';
// Strip HTML if the AI output includes tags (Slack doesn't render them)
const stripped = rawContent.replace(/<[^>]+>/g, '').trim();
const truncated = stripped.length > MAX_CHARS
? stripped.slice(0, MAX_CHARS) + '...
_(message truncated for Slack — full version in email)_'
: stripped;
return [{ json: { ...$json, slack_content: truncated } }];
Then in the Slack HITL node, reference {{ $json.slack_content }} instead of the raw AI output.
One other option worth knowing: if the full email body genuinely needs to be reviewed, you can store it in a Google Doc or a temp file and include just the link in the Slack message. The reviewer opens the doc for full context but approves/rejects in Slack. Keeps the HITL node well within limits and scales to any content length.
the Google Doc redirect pattern is a smart one — it sidesteps the limit entirely and keeps the HITL message clean and quick to scan, which matters a lot when you’re doing multiple approvals in a row.
Thanks @Benjamin_Behrens and @OMGItsDerek! Very insightful, good to have confirmation. I might go with the simple fix with truncation and then consider the “external”/Google Docs approach if needed.
The crux of the issue that I guess I was trying to raise is how difficult it is to identify the issue, though. As in: invalid_blocks being the error shown, along with the uncertainty of the AI-generated content’s validity (it appeared empty when the error was applicable) made it quite difficult to pinpoint the real issue.
Anyway, hopefully this can help others experiencing the same issue in the future.
Good plan — truncation first, Google Docs fallback if needed is the right call. And you’re right that invalid_blocks is a particularly frustrating error to debug; without a pointer to which field or block actually exceeded the limit you’re essentially guessing. A more descriptive error message from n8n (or even Slack) would save a lot of time there. Glad this thread can help others hit the same wall.