OrchardCMS/OrchardCore · error · TypeError

Thenable self-resolution

Error message

Thenable self-resolution

What it means

Same Promises/A+ self-resolution guard as the full build: jQuery's Deferred (present in the slim build) throws this TypeError when a resolution handler returns the very promise being resolved, which would create an unresolvable cycle.

Solutions

  1. Find the handler in the stack that returns the promise and return a new Deferred's promise, a plain value, or another (different) promise instead.
  2. Add a guard before resolving: throw if the candidate value === the deferred's own promise.
  3. Refactor shared deferreds so each logical operation creates its own Deferred instance.
  4. Prefer native Promises or $.when over manually returning deferred.promise() inside its own chains.

Example fix

// before
promise.then(function loop() {
  return promise; // TypeError: Thenable self-resolution
});
// after
promise.then(function (v) {
  return retry(v); // return a NEW promise
});
Defensive patterns

Strategy: type-guard

Validate before calling

function resolveSafely(d, v) {
  if (v && v.then && v === d.promise()) { return $.Deferred().reject(new TypeError('self-resolution blocked')); }
  d.resolve(v);
}

Type guard

function isThenable(v) { return !!v && (typeof v === 'object' || typeof v === 'function') && typeof v.then === 'function'; }
function isOwnPromise(d, v) { return isThenable(v) && v === d.promise(); }

Try / catch

$.when(promise).then(h).fail(function (e) { if (e && e.message === 'Thenable self-resolution') { recoverChain(); } });

Prevention

When it happens

Trigger: A .then()/.pipe()/.state()-chain handler returning the same deferred.promise(); resolving a deferred with its own promise object.

Common situations: Retry/recursion wrappers accidentally returning the outer deferred; shared module-level deferreds reused across calls; callback-to-promise refactors that return the same promise from within its own then handler.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/7a5c8fc77b0a11d4. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Vendor/jquery-3.5.1/jquery.slim.js:3767

						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)