bolt-python
bolt-python copied to clipboard
value of `plain_text_input` element in dialog block cannot be cleared
(Filling out the following details about bugs will help us solve your issue sooner.)
Reproducible in:
The slack_bolt
version
slack-bolt==1.13.1 slack-sdk==3.16.0
Python runtime version
Python 3.10.4
OS info
#51-Ubuntu SMP Thu Aug 11 07:51:15 UTC 2022
Steps to reproduce:
I have a bot which presents the user with a button. When the user clicks the button, a dialog is opened using app.client.views_open()
. The dialog's view
contains an input
block which in turn declares "optional": True
and then a plain_text_input
element.
Now, this is where it gets a bit strange. Earlier today the user would get an error presented that input is required when pressing the dialog's Submit
button. But now there is an indicator that the input is indeed optional. But when the user clears the input text and presses submit (or even replaces the input with one or multiple spaces), the original input value is kept. I am quite positive that I restarted my bot properly earlier today, so I don't understand how the behavior could change during the day.
In any case, a user should be able to clear the text of an optional plain_text_input
in a dialog.
Expected result:
See above.
Actual result:
See above.
Hi @knutwannheden 👋🏻 Thanks for reaching out when you came across this issue!
I took sometime to look into the status of the Slack API. Today there were some updates made to optional input fields, so this may have been related to your experience!
I've setup a test app that uses an optional input
with a plain_text_input
element. It appear to work correctly when receiving the submitted values. I also played with an initial_value
to re-create your behaviour where the input's original value was kept when you submitted with spaces. On my side, the submitted values appear correct.
Here is the block kit sample that I used:
{
"type": "input",
"optional": true,
"element": {
"type": "plain_text_input",
"action_id": "plain_text_input-action",
"initial_value": "An initial value"
},
"label": {
"type": "plain_text",
"text": "Label",
"emoji": true
}
}
🕥 Now that some time has passed, are you still experiencing this odd behaviour? If so, can you provide us with a code sample that we can use to re-create your issue. 🙇🏻
Take care!
@mwbrooks Those updates you mention probably explain why the behavior changed then.
I just tested it again and I still can't get it to work. When I clear the input (which had an initial value as you correctly assumed) and press "Submit" I see the following "invalid_blocks" error in my bot's log, which I otherwise don't have:
DEBUG:slack_sdk.webhook.client:Received the following response - status: 404, headers: {'date': 'Fri, 16 Sep 2022 18:58:15 GMT', 'server': 'Apache', 'x-powered-by': 'HHVM/4.153.1', 'x-frame-options': 'SAMEORIGIN', 'access-control-allow-origin': '*', 'referrer-policy': 'no-referrer', 'x-slack-backend': 'r', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'x-xss-protection': '0', 'vary': 'Accept-Encoding', 'content-type': 'application/json; charset=utf-8', 'x-envoy-upstream-service-time': '172', 'x-backend': 'main_normal main_bedrock_normal_with_overflow main_canary_with_overflow main_bedrock_canary_with_overflow main_control_with_overflow main_bedrock_control_with_overflow', 'x-server': 'slack-www-hhvm-main-iad-gkfs', 'x-slack-shared-secret-outcome': 'no-match', 'via': 'envoy-www-iad-blnx, envoy-edge-fra-t4lm', 'x-edge-backend': 'envoy-www', 'x-slack-edge-shared-secret-outcome': 'no-match', 'connection': 'close', 'transfer-encoding': 'chunked'}, body: {"ok":false,"error":"invalid_blocks"}
Here is what my dialog looks like:
app.client.views_open(
trigger_id=body["trigger_id"],
view={
"type": "modal",
"callback_id": "my_callback",
"private_metadata": my_metadata,
"title": {"type": "plain_text", "text": "Lobbybot"},
"submit": {"type": "plain_text", "text": "Submit"},
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": my_label
}
},
{
"type": "input",
"block_id": "tweet_input_block",
"label": {"type": "plain_text", "text": "Text"},
"optional": True,
"element": {
"type": "plain_text_input",
"action_id": "my_text",
"initial_value": my_initial_value,
"multiline": True,
"focus_on_load": True
}
}
]
}
)
My dialog's content looks very similar to your example. Could it be related to the "multiline": true
setting? Hopefully you will be able to work it out!
I should also mention that my handler (which would here be "my_callback") reads the value from the dialog and then copies it to another text field in the original message (done using respond(replace_original=True)
). In the original the text field is declared like this:
{
"type": "section",
"block_id": "my_block",
"text": {
"text": "Some text",
"type": "mrkdwn"
},
"fields": [
{
"type": "mrkdwn",
"text": "A"
},
{
"type": "mrkdwn",
"text": "B"
},
{
"type": "plain_text",
"text": "C"
},
{
"type": "plain_text",
"text": "D"
}
]
},
The dialog's text gets copied to the field which here has the text "C". Does a "plain_text" field in a "secion" block's "fields" maybe not support empty values?
Hey @knutwannheden, are you able to share the handler and all related code? That would be easier for me to reproduce.
I'm also curious what sort of data you are storing the private_metadata
field (for reproducibility's sake).
The dialog's text gets copied to the field which here has the text "C". Does a "plain_text" field in a "secion" block's "fields" maybe not support empty values?
You might be on to something here. Looking at the reference documentation for the section
Block Kit element I see this bit about the block_id
(emphases mine):
A string acting as a unique identifier for a block. If not specified, one 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 newblock_id
.
Are you by any chance using the same block_id when updating the message?
Yes, it appears to be the case that the "plain_text" field doesn't allow for empty values. AFAICT there is no "optional" property I can set there. As a workaround I set the field to a single blank in my handler.
So, while I was first going to report an issue with the dialog (which got fixed while I reported it, basically), I think it now turns out that the issue is with the "plain_text" field in a "section" block. I am using the "fields" construct here, because I want the fields to be rendered using two columns.
Hey @knutwannheden, are you able to share the handler and all related code? That would be easier for me to reproduce.
I'm also curious what sort of data you are storing the
private_metadata
field (for reproducibility's sake).
I am unsure how helpful that would be in the end. But here is what I want to do: My bot proposes a Twitter tweet to be posted in a Slack message. The user can push an "Edit" button which brings up the dialog, where the Tweet can be adjusted, if necessary. When pressing "Submit" the edited text gets copied back to the original message and the user pushes the "Post" button to publish the tweet. Now there are in fact two fields (one for a German tweet the other for a French tweet) and if the user clears the text in the dialog, then no tweet should be posted for the respective language.
This is where I use the private_metadata
. When I open the dialog I save the original message in a global dict using a unique key and then pass this key to the dialog using private_metadata
, so that the handler later can modify the original message. This is very ugly, but I couldn't figure out how else to achieve this.
Are you by any chance using the same block_id when updating the message?
Hmm... I will have to look into this. But the fact that everything works as long as the user doesn't enter an empty text into the dialog, makes me think it can't be related to the block_id
.
Btw, thank you very much for the very speedy feedback!
OK, yes, I have confirmed your suspicion! Indeed it looks like these plain_text
elements under the fields
of a section
Block Kit element cannot have a zero-length string as text
!
As a starting point I will see about getting our documentation updated. Secondly, I'll see what can be done to provide a better error message from the API. That must have been a frustrating experience - apologies for that!
A really good way to highlight the issue is:
Thank you for your help and patience!