appsmithorg/appsmith · error · FoundPromiseInSyncEvalError
Found a Promise() during evaluation. Data fields cannot exec
Error message
Found a Promise() during evaluation. Data fields cannot execute asynchronous code.
What it means
FoundPromiseInSyncEvalError thrown by the eval worker when a data-field binding returns a Promise. Data fields (Text.value, Input.defaultText, container background, etc.) are evaluated synchronously by indirectEval, so any returned Promise is unawaitable and would silently render [object Promise]. The error surfaces that the user must move the logic to an async context. The thrown error then routes through errorModifier.run alongside ActionInDataFieldErrorModifier and TypeErrorModifier.
Source
Thrown at app/client/src/workers/Evaluation/evaluate.ts:436
isTriggerBased: isJSCollection,
});
Object.assign(EVAL_CONTEXT, dataTreeContext);
}
overrideEvalContext(EVAL_CONTEXT, context?.overrideContext);
Object.assign(self, EVAL_CONTEXT);
try {
result = indirectEval(script);
if (result instanceof Promise) {
/**
* If a promise is returned in data field then show the error to help understand data field doesn't await to resolve promise.
* NOTE: Awaiting for promise will make data field evaluation slower.
*/
throw new FoundPromiseInSyncEvalError();
}
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
const { errorCategory, errorMessage, rootcause } = errorModifier.run(
error,
{ userScript: error.userScript || userScript, source: error.source },
[ActionInDataFieldErrorModifier, TypeErrorModifier],
);
errors.push({
errorMessage,
severity: Severity.ERROR,
raw: script,
errorType: PropertyEvaluationErrorType.PARSE,
originalBinding: userScript,
kind: {
category: errorCategory,View on GitHub (pinned to 8cd9021c24)
Solutions
- Reference the query's cached result instead of calling it: {{ getApi.data }}.
- Move async logic into a JS object function and trigger it via an event (onPageLoad, onClick), then bind to the JS object's result property.
- Use the onSuccess callback of the action to refresh data the binding depends on.
- Avoid fetch/Promise/await inside moustache bindings entirely.
Example fix
// before — Text widget value
{{ getApi.run() }} // returns a Promise -> error
// after
{{ getApi.data }} // resolved data, populated after run
// or move to JS object
export default {
async load() { this.data = await getApi.run(); }
};
// bind widget to {{ JSObject.data }} Defensive patterns
Strategy: type-guard
Validate before calling
// Never call async code from a data field; route through a JS object
// JS object
export default {
async load() { this.users = await getApi.run(); }
};
// widget binding uses {{ JSObject.users }}, not {{ getApi.run() }} Type guard
function returnsPromise(v: unknown): v is Promise<unknown> {
return v != null && typeof (v as Promise<unknown>).then === 'function';
} Prevention
- In data fields, bind to .data / .result properties of actions, never call them.
- Move any await/fetch/Promise into a JS object triggered by events.
- Treat the error message as authoritative: data fields are synchronous by design.
When it happens
Trigger: Binding a query directly: {{ getApi.run() }}; calling a JS object method that is async or returns a Promise; using fetch/await/Promise.then inside a data field; referencing a library function that returns a Promise.
Common situations: New users referencing the query function instead of its result; migrating from a JS object where async was fine into a data field; calling moment().then() or lodash debounce in a binding.
Related errors
- Please remove any direct/indirect references to {{actionName
- Failed to load JS libraries
- The script at ${url} cannot be installed.
- Unable to determine a unique accessor
- Failed to generate autocomplete definitions for ${name}.
AI-assisted analysis of appsmithorg/appsmith@8cd9021c24 (2026-08-12).
Data as JSON: /api/errors/42f77fdd6d97becc.
Report an issue: GitHub.