{"record":{"id":"9bc0724d835a622f","repo":"appsmithorg/appsmith","slug":"showalert-expected-string-for-message-argument-b","errorCode":null,"errorMessage":"showAlert expected STRING for 'message' argument but received ${received}","messagePattern":"showAlert expected STRING for 'message' argument but received (.+?)","errorType":"validation","errorClass":"ActionValidationError","httpStatus":null,"severity":"error","filePath":"app/client/src/sagas/ActionExecution/ShowAlertActionSaga.ts","lineNumber":18,"sourceCode":"import AppsmithConsole from \"utils/AppsmithConsole\";\nimport { ActionValidationError } from \"sagas/ActionExecution/errorUtils\";\nimport { getType, Types } from \"utils/TypeHelpers\";\nimport type { ToastKind } from \"@appsmith/ads\";\nimport type { TShowAlertDescription } from \"workers/Evaluation/fns/showAlert\";\nimport { call } from \"redux-saga/effects\";\nimport showToast from \"sagas/ToastSagas\";\nimport { uniqueId } from \"lodash\";\nimport type { SourceEntity } from \"entities/AppsmithConsole\";\n\nexport default function* showAlertSaga(\n  action: TShowAlertDescription,\n  source?: SourceEntity,\n) {\n  const { payload } = action;\n\n  if (typeof payload.message !== \"string\") {\n    throw new ActionValidationError(\n      \"SHOW_ALERT\",\n      \"message\",\n      Types.STRING,\n      getType(payload.message),\n    );\n  }\n\n  // This is the toast that is rendered which is user generated by using `showAlert` platform function. This is forceDisplayed no matter the conditions.\n  yield call(\n    showToast,\n    payload.message,\n    {\n      kind: payload.style as ToastKind,\n      toastId: uniqueId(\"ToastId\"),\n    },\n    { forceDisplay: true },\n  );\n  AppsmithConsole.info({","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/appsmithorg/appsmith/blob/8cd9021c24cdbea1c3c12c966073708e83db60c2/app/client/src/sagas/ActionExecution/ShowAlertActionSaga.ts#L1-L36","documentation":"ActionValidationError thrown by showAlertSaga when payload.message is not a string. showAlert builds a toast, and toasts require a string body, so the saga validates the argument type synchronously before calling showToast. The error message is rendered via the TRIGGER_ACTION_VALIDATION_ERROR template.","triggerScenarios":"Calling showAlert() with a number, object, array, undefined, or null message; binding message to a query response that resolves to an object (e.g. an entire API response) rather than a string field.","commonSituations":"Binding {{ getApi.data }} (object) instead of {{ getApi.data.message }}; passing a raw JS object literal; chaining showAlert after an action that returned undefined.","solutions":["Pass a string literal: showAlert('Saved', 'success').","Drill into the specific string field: showAlert(getApi.data.message).","Coerce with String(...) or fall back to a default when the bound value may be missing."],"exampleFix":"// before\nshowAlert(getApi.data); // object\n// after\nshowAlert(getApi.data.message ?? 'No message');","handlingStrategy":"type-guard","validationCode":"const msg = typeof payload === 'string' ? payload : String(payload ?? '');\nif (!msg) { showAlert('Message is required', 'error'); return; }\nshowAlert(msg, 'success');","typeGuard":"function isAlertMessage(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  showAlert(message);\n} catch (e) {\n  if (e instanceof ActionValidationError) console.warn(e.message);\n}","preventionTips":["Always drill into a specific string field of a query response before showing it.","Default to a fallback string when a binding may be undefined.","Avoid passing raw objects or arrays to showAlert."],"tags":["show-alert","toast","validation","argument-type"],"backgroundTag":null,"analyzedSha":"8cd9021c24cdbea1c3c12c966073708e83db60c2","analyzedAt":"2026-08-12T22:14:19.293Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}