{"record":{"id":"a15c71ac2d2b88be","repo":"appsmithorg/appsmith","slug":"please-remove-any-direct-indirect-references-to","errorCode":null,"errorMessage":"Please remove any direct/indirect references to {{actionName}} and try again. Data fields cannot execute framework actions.","messagePattern":"Please remove any direct/indirect references to (.+?)\\} and try again\\. Data fields cannot execute framework actions\\.","errorType":"exception","errorClass":"ActionCalledInSyncFieldError","httpStatus":null,"severity":"error","filePath":"app/client/src/workers/Evaluation/fns/utils/fnGuard.ts","lineNumber":37,"sourceCode":"    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    value: function (...args: any[]) {\n      const fnWithGuards = getFnWithGuards(fn, fnName, fnGuards);\n\n      return fnWithGuards(...args);\n    },\n    enumerable: false,\n    writable: true,\n    configurable: true,\n  });\n}\n\nexport function isAsyncGuard<P extends ReadonlyArray<unknown>>(\n  fn: (...args: P) => unknown,\n  fnName: string,\n) {\n  if (self.$isDataField) {\n    self[\"$isAsync\"] = true;\n    throw new ActionCalledInSyncFieldError(fnName);\n  }\n}\n\nexport function getFnWithGuards(\n  // TODO: Fix this the next time the file is edited\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  fn: (...args: any[]) => unknown,\n  fnName: string,\n  fnGuards: FnGuard[],\n) {\n  // TODO: Fix this the next time the file is edited\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  return (...args: any[]) => {\n    for (const guard of fnGuards) {\n      guard(fn, fnName);\n    }\n\n    return fn(...args);","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/appsmithorg/appsmith/blob/8cd9021c24cdbea1c3c12c966073708e83db60c2/app/client/src/workers/Evaluation/fns/utils/fnGuard.ts#L19-L55","documentation":"Thrown by the isAsyncGuard wrapping every framework action exposed to the evaluation worker (e.g. showAlert, navigateTo, storeValue, setInterval/setTimeout overrides, geolocation, and setter methods wired through getFnWithGuards). Appsmith classifies bindings into data fields (self.$isDataField === true: properties that merely store data, such as Input.defaultText, Table.tableData, or a plain JS object property) and action fields (onClick, onRowSelect, JS object functions). When an action-wrapped function is invoked while $isDataField is true, the guard sets self.$isAsync = true and throws ActionCalledInSyncFieldError(actionName), whose message substitutes {{actionName}} with fnName + '()'. The rule exists because data fields are evaluated synchronously and must stay free of side effects.","triggerScenarios":"Writing appsmith.actions.showAlert('hi') or navigateTo(url) inside a data property such as Input1.defaultText, Table1.tableData, or a non-function property of a JS object; calling setInterval/setTimeout or appsmith.geolocation.getCurrentPosition() in a data field; indirectly referencing an action inside an IIFE or helper that runs during data-field evaluation.","commonSituations":"New users assuming every binding can trigger actions; refactoring an onClick handler into a default value; calling a JS object function that internally invokes an action, from within a data field; copy-pasting a workflow snippet into the wrong property.","solutions":["Move the action call into an action/event field (the widget's onClick/onSuccess, or a JS object function) rather than a data field.","If you need the action driven by a value change, bind the action field to run on the onChange event of the source widget instead of computing it inline in the data field.","Replace side-effecting logic in a data field with a pure expression; store the result of async work via storeValue from an action and read that stored value in the data field.","Search the data field binding for the named action (the message includes actionName) and remove every direct/indirect reference to it."],"exampleFix":"// before (Input1.defaultText - a DATA field)\n\"Welcome \" + (function(){ appsmith.actions.showAlert('set'); return user.name })()\n\n// after\n// Input1.defaultText (data field, pure):\n\"Welcome \" + user.name\n// Input1.onTextChanged (action field):\nappsmith.actions.showAlert('name set')","handlingStrategy":"validation","validationCode":"// Structural validation: never call action functions inside a data field.\n// Data fields (self.$isDataField === true) include widget value/default properties\n// and plain JS-object properties. Action functions (wrapped by isAsyncGuard) are\n// showAlert, navigateTo, storeValue, setInterval/setTimeout overrides, geolocation,\n// and setter methods.\n//\n// Rule: if a binding only STORES data, keep it a pure expression; if it must DO\n// something, move it into an action/event field (onClick, onSuccess, a JS fn).","typeGuard":"// There is no safe runtime call to make here: the guard fires at invocation.\n// The 'type guard' is structural - know which binding is a data field vs action:\nconst ACTION_NAMES = new Set([\n  'showAlert', 'navigateTo', 'storeValue', 'removeValue', 'clearStore',\n  'download', 'copyToClipboard', 'resetWidget', 'setInterval', 'setTimeout',\n  'clearInterval', 'clearTimeout',\n]);\nconst isFrameworkAction = (name) => ACTION_NAMES.has(name);\n// Never reference isFrameworkAction(name) inside a data field binding.","tryCatchPattern":"// try/catch will NOT make an action legal in a data field - it only suppresses\n// the guard. The correct pattern is to relocate the call:\n//\n// BAD (data field Input1.defaultText):\n//   (appsmith.actions.showAlert('x'), user.name)\n// GOOD:\n//   Input1.defaultText -> user.name\n//   Input1.onTextChanged -> appsmith.actions.showAlert('x')","preventionTips":["Treat any binding that stores a value (defaultText, text, tableData, options, sourceData, plain JS-object props) as a data field: pure expressions only.","Put side-effecting calls only in event/action fields: onClick, onRowSelect, onSuccess, onError, onTextChanged, or a JS object function.","If async work must feed a data field, run it in an action that calls storeValue, then read that stored value in the data field.","When you see the message, search the named binding for actionName (with '()') and remove every direct and indirect reference."],"tags":["evaluation","appsmith-api","data-field","async-guard","security"],"backgroundTag":null,"analyzedSha":"8cd9021c24cdbea1c3c12c966073708e83db60c2","analyzedAt":"2026-08-12T22:14:19.293Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}