{"record":{"id":"13b31a871a7e9314","repo":"OrchardCMS/OrchardCore","slug":"thenable-self-resolution-jquery","errorCode":null,"errorMessage":"Thenable self-resolution","messagePattern":"Thenable self-resolution","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Vendor/jquery-3.5.1/jquery.js","lineNumber":3767,"sourceCode":"\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n","sourceCodeStart":3749,"sourceCodeEnd":3785,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Vendor/jquery-3.5.1/jquery.js#L3749-L3785","documentation":"This TypeError is thrown by jQuery's Promise implementation when a promise resolution handler returns the deferred's own promise — i.e. a promise is resolved with itself. The Promises/A+ spec (section 2.3.1) forbids self-resolution because it creates an unresolvable cycle, so jQuery deliberately fails the deferred with this TypeError instead of hanging forever.","triggerScenarios":"Inside a .then()/.pipe() handler (or Deferred resolution chain), returning the same deferred.promise() object that is being resolved — e.g. `return d.promise()` from a handler attached to `d.promise()` itself, or resolving a deferred with its own promise.","commonSituations":"Chaining retries where a handler mistakenly returns the original deferred instead of a new one; recursive wrapper functions that accidentally return the outer promise; converting callback code to promises and reusing a single module-level deferred; mistakenly returning `arguments.callee`-style same-promise from .then.","solutions":["Inspect the .then/.pipe handler on the stack: change it to return a NEW promise/deferred, not the same deferred.promise() it is chained on.","If resolving a deferred with another promise, verify the value !== the deferred's own promise before resolve().","Refactor to return the value (or $.Deferred-based promise created inside the handler) rather than the enclosing deferred.","Where cycles are possible, guard: if (candidate === myPromise) { throw new TypeError('self-resolution'); } before resolving."],"exampleFix":"// before\nfunction run() {\n  const d = $.Deferred();\n  d.then(() => d.promise()); // TypeError: Thenable self-resolution\n  return d.promise();\n}\n// after\nfunction run() {\n  return $.Deferred(async (d) => {\n    const result = await step();\n    d.resolve(result); // resolve with a value or a DIFFERENT promise\n  }).promise();\n}","handlingStrategy":"type-guard","validationCode":"function safeResolve(d, value) {\n  if (value === d.promise()) throw new TypeError('Cannot resolve deferred with its own promise');\n  d.resolve(value);\n}","typeGuard":"function isSelfResolution(d, value) { return value != null && (typeof value === 'object' || typeof value === 'function') && typeof value.then === 'function' && value === d.promise(); }","tryCatchPattern":"promise.then(handler).catch(function (e) { if (e instanceof TypeError && e.message === 'Thenable self-resolution') { return rebuildChain(); } throw e; });","preventionTips":["Never return the same deferred.promise() from a handler attached to that promise.","Create a fresh Deferred per logical operation instead of reusing module-level deferreds.","When resolving with a thenable, check it is not the target promise itself.","Favor async/await with native Promises, which surface self-resolution consistently."],"tags":["jquery","promise","deferred","promises-aplus"],"backgroundTag":"internal-invariant-violation","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}