I am migrating a legacy Google Chat bot to the new Google Workspace Add-ons using a custom Python HTTP endpoint. I am trying to open a dialog when a user triggers a specific slash command (/k8s_access).
My backend receives the POST request and returns a synchronous JSON response containing the actionResponse envelope to open the dialog. However, the dialog completely fails to render in the Google Chat UI. The error in UI is like this:
Could not load dialog. Either the app is not responding or the response is invalid
My Setup & What I’ve Verified:
App Configuration: In the Google Cloud Console (Workspace Marketplace SDK), the /k8s_access slash command is configured and the “Opens a dialog” checkbox is explicitly enabled.
Routing: My Python HTTP endpoint successfully receives the payload from Google’s service agent, so this is not an IAM/firewall blocking issue in the first request. But in the second attempt, when the user clicks on Submit button, it fails without even calling my backend application.
Response Type: I am returning the JSON synchronously back to the incoming HTTP request, not making a separate asynchronous POST request to the Chat API.
The Code: Here is the Python logic handling the command and building the response. I am using the Cards V2 schema:
def handle_k8s_access_command(event) -> JsonResponse:
"""Handle the /k8s_access command to show a dialog for requesting K8s cluster access."""
logger.info(f"Received /k8s_access command from {event.user.email}")
dialog = Dialog(
header=Header(title="Request K8s Access"),
sections=[
Section(header="Cluster Details").add_widget(
TextInput(
name="cluster_name",
label="Cluster Name",
hint="Enter the Kubernetes cluster name"
)
)
],
fixed_footer=FixedFooter(
primary_button=PrimaryButton(
text="Submit",
function="handle_submit_k8s_access"
)
)
)
return JsonResponse(dialog.to_dict())
class Dialog:
def __init__(
self,
header: "Header",
sections: List["Section"],
fixed_footer: "FixedFooter" = None,
):
self.header = header
self.sections = sections
self.fixed_footer = fixed_footer
def to_dict(self):
body = {
"sections": [section.to_dict() for section in self.sections]
}
if self.header:
body["header"] = self.header.to_dict()
if self.fixed_footer:
body["fixedFooter"] = self.fixed_footer.to_dict()
return {
"action": {
"navigations": [
{
"pushCard": body
}
]
}
}
class FixedFooter:
def __init__(self, primary_button: "PrimaryButton" = None):
self.primary_button = primary_button
def to_dict(self):
return {
"primaryButton": self.primary_button.to_dict()
if self.primary_button
else None
}
The Output JSON: This is the exact dictionary being passed to JsonResponse and sent back to Google:
{
"action": {
"navigations": [
{
"pushCard": {
"header": {
"title": "Request K8s Access",
"imageUrl": "https://storage.googleapis.com/platformgpt-backend/icons/form.png",
"imageType": "CIRCLE"
},
"sections": [
{
"header": "Cluster Details",
"collapsible": false,
"widgets": [
{
"textInput": {
"name": "cluster_name",
"label": "Cluster Name",
"hintText": "Enter the Kubernetes cluster name"
}
}
]
}
],
"fixedFooter": {
"primaryButton": {
"text": "Submit",
"onClick": {
"action": {
"function": "handle_submit_k8s_access"
}
}
}
}
}
}
]
}
}
I would appreciate any ideas for debugging this it has already taken up a lot of my time
the error log in GCP cloud logging:
{
"insertId": "SECRET",
"jsonPayload": {
"deployment": "projects/chat/keys/SECRET",
"deploymentFunction": "handle_submit_k8s_access",
"@type": "type.googleapis.com/google.cloud.gsuiteaddons.logging.v1.GSuiteAddOnsLogEntry",
"error": {
"message": "Unspecified error invoking the add-on.",
"code": 13
}
},
"resource": {
"type": "g_suite_add_ons",
"labels": {
"project_id": "SECRET",
"deployment": "projects/chat/keys/SECRET"
}
},
"timestamp": "2026-02-22T14:16:46.566624Z",
"severity": "ERROR",
"logName": "projects/SECRET/logs/gsuiteaddons.googleapis.com%2Ferrors",
"receiveTimestamp": "2026-02-22T14:16:47.064463042Z"
}
The log in my backend django, on first attempt (inputing the command k8s_access ):
[22/Feb/2026:17:26:06 +0000] “POST /hook/message/ HTTP/1.1” 200 506 “-” “Google-gsuiteaddons”
And no log (even trace) on submit, I’m pretty sure that clicking on submit do not call the backend.
I even tried to implement it via a message card v2 api (not dialog), it goes exactly the same, it renders the form in a card for user in the chat, but when you click on submit you got another error in google chat UI without even calling the backend:
I am migrating a legacy Google Chat bot to the new Google Workspace Add-ons using a custom Python HTTP endpoint. I am trying to open a dialog when a user triggers a specific slash command (/k8s_access).
My backend receives the POST request and returns a synchronous JSON response containing the actionResponse envelope to open the dialog. However, the dialog completely fails to render in the Google Chat UI. The error in UI is like this:
Could not load dialog. Either the app is not responding or the response is invalid
My Setup & What I’ve Verified:
App Configuration: In the Google Cloud Console (Workspace Marketplace SDK), the
/k8s_accessslash command is configured and the “Opens a dialog” checkbox is explicitly enabled.Routing: My Python HTTP endpoint successfully receives the payload from Google’s service agent, so this is not an IAM/firewall blocking issue in the first request. But in the second attempt, when the user clicks on Submit button, it fails without even calling my backend application.
Response Type: I am returning the JSON synchronously back to the incoming HTTP request, not making a separate asynchronous POST request to the Chat API.
The Code: Here is the Python logic handling the command and building the response. I am using the Cards V2 schema:
The Output JSON: This is the exact dictionary being passed to JsonResponse and sent back to Google:
I would appreciate any ideas for debugging this it has already taken up a lot of my time
the error log in GCP cloud logging:
{ "insertId": "SECRET", "jsonPayload": { "deployment": "projects/chat/keys/SECRET", "deploymentFunction": "handle_submit_k8s_access", "@type": "type.googleapis.com/google.cloud.gsuiteaddons.logging.v1.GSuiteAddOnsLogEntry", "error": { "message": "Unspecified error invoking the add-on.", "code": 13 } }, "resource": { "type": "g_suite_add_ons", "labels": { "project_id": "SECRET", "deployment": "projects/chat/keys/SECRET" } }, "timestamp": "2026-02-22T14:16:46.566624Z", "severity": "ERROR", "logName": "projects/SECRET/logs/gsuiteaddons.googleapis.com%2Ferrors", "receiveTimestamp": "2026-02-22T14:16:47.064463042Z" }The log in my backend django, on first attempt (inputing the command k8s_access ):
And no log (even trace) on submit, I’m pretty sure that clicking on submit do not call the backend.
I even tried to implement it via a message card v2 api (not dialog), it goes exactly the same, it renders the form in a card for user in the chat, but when you click on submit you got another error in google chat UI without even calling the backend: