OrchardCMS/OrchardCore · error · TypeError
Thenable self-resolution
Error message
Thenable self-resolution
What it means
Same Promises/A+ guard as in jquery.js, present in jquery.slim.js: a jQuery Deferred throws TypeError "Thenable self-resolution" when a promise is resolved (or a .then handler returns) with the promise object itself. Self-resolution would loop forever, so the spec mandates rejection with this TypeError.
Solutions
- Resolve with the concrete value or a distinct promise, never the same promise/deferred object.
- Audit .then() callbacks for returns of the outer promise variable; return the payload or a new promise instead.
- Restructure recursive promise code so each recursion creates a fresh deferred, or convert to async/await.
- Guard with a check: if (value === myPromise) throw/handle before resolving.
Example fix
// before
promise.then(function () {
return promise; // self-resolution
});
// after
promise.then(function (result) {
return process(result); // return a value or a different promise
}); Defensive patterns
Strategy: type-guard
Validate before calling
function resolveSafe(deferred, value) {
if (value && (value === deferred || value === deferred.promise())) return; // skip self-resolution
deferred.resolve(value);
} Type guard
function isSamePromise(p, v) { return v === p; } Try / catch
promise.catch(function (err) {
if (err instanceof TypeError && err.message === 'Thenable self-resolution') {
// break the cycle: re-run with corrected resolution value
} else { throw err; }
}); Prevention
- Never resolve a deferred with its own promise object.
- Return values or other promises — not the current chain — from .then() handlers.
- In memoized async helpers, guard cached promises against being passed as resolution values.
- Prefer async/await for recursive flows to surface cycles as clearer errors.
When it happens
Trigger: deferred.resolve(deferred.promise()); returning the same promise from inside its own .then() handler; a function that both creates a deferred and resolves it with its own promise (e.g. in recursive or cached-promise patterns).
Common situations: Memoized async functions that cache the promise and pass it back as the resolution value; refactors that accidentally alias the outer promise; chains where a handler intended to return data but returned the chain itself.
Related errors
- Thenable self-resolution
- Thenable self-resolution
- Thenable self-resolution
- Thenable self-resolution
- Thenable self-resolution
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/c1bee88315eedc81.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Vendor/jquery-3.6.0/jquery.slim.js:3771
return function() {
var that = this,
args = arguments,
mightThrow = function() {
var returned, then;
// Support: Promises/A+ section 2.3.3.3.3
// https://promisesaplus.com/#point-59
// Ignore double-resolution attempts
if ( depth < maxDepth ) {
return;
}
returned = handler.apply( that, args );
// Support: Promises/A+ section 2.3.1
// https://promisesaplus.com/#point-48
if ( returned === deferred.promise() ) {
throw new TypeError( "Thenable self-resolution" );
}
// Support: Promises/A+ sections 2.3.3.1, 3.5
// https://promisesaplus.com/#point-54
// https://promisesaplus.com/#point-75
// Retrieve `then` only once
then = returned &&
// Support: Promises/A+ section 2.3.4
// https://promisesaplus.com/#point-64
// Only check objects and functions for thenability
( typeof returned === "object" ||
typeof returned === "function" ) &&
returned.then;
// Handle a returned thenable
if ( isFunction( then ) ) {
View on GitHub (pinned to 4306c0717f)