{"record":{"id":"0638823158657918","repo":"guzzle/promises","slug":"cannot-fulfill-or-reject-a-promise-with-itself","errorCode":null,"errorMessage":"Cannot fulfill or reject a promise with itself","messagePattern":"Cannot fulfill or reject a promise with itself","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/Promise.php","lineNumber":178,"sourceCode":"    public function reject($reason): void\n    {\n        $this->settle(self::REJECTED, $reason);\n    }\n\n    private function settle(string $state, $value): void\n    {\n        if ($this->state !== self::PENDING) {\n            // Ignore calls with the same resolution.\n            if ($state === $this->state && $value === $this->result) {\n                return;\n            }\n            throw $this->state === $state\n                ? new \\LogicException(\"The promise is already {$state}.\")\n                : new \\LogicException(\"Cannot change a {$this->state} promise to {$state}\");\n        }\n\n        if ($value === $this) {\n            throw new \\LogicException('Cannot fulfill or reject a promise with itself');\n        }\n\n        // Clear out the state of the promise but stash the handlers.\n        $this->state = $state;\n        $this->result = $value;\n        $handlers = $this->handlers;\n        $this->handlers = null;\n        $this->waitList = $this->waitFn = null;\n        $this->cancelFn = null;\n\n        if (!$handlers) {\n            return;\n        }\n\n        // If the value was not a settled promise or a thenable, then resolve\n        // it in the task queue using the correct ID.\n        if (!is_object($value) || !method_exists($value, 'then')) {\n            $id = $state === self::FULFILLED ? 1 : 2;","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/guzzle/promises/blob/42118e66a53c492effaf92bc357e931985d5c6f9/src/Promise.php#L160-L196","documentation":"Promise::settle() throws this LogicException when a promise is fulfilled or rejected with itself as the settling value ($value === $this). A self-referencing resolution would create an unresolvable cycle, so the library rejects it eagerly with a clear invariant violation instead of hanging or recursing infinitely.","triggerScenarios":"Calling $promise->resolve($promise) or $promise->reject($promise) on the very same Promise instance; passing the promise back as the result from inside its own wait function or a resolver callback.","commonSituations":"Recursive/async code that returns the promise itself instead of its eventual value; forwarding functions like function fwd($p){ return $p->resolve($p); } meant to pass through a thenable; copy-paste in wrapper classes that confuse the wrapper with the inner promise.","solutions":["Return the promise from your function instead of resolving it with itself (thenables are unwrapped automatically).","Resolve with the actual awaited value or a different promise object, never $this.","In custom PromiseInterface implementations, assert $value !== $this before delegating to settle()."],"exampleFix":"// before\nfunction passThrough($p) { $p->resolve($p); return $p; } // LogicException\n// after\nfunction passThrough($p) { return $p; } // promise returned; callers can then() it","handlingStrategy":"validation","validationCode":"if ($value === $promise) {\n    throw new \\InvalidArgumentException('Cannot settle a promise with itself');\n}\n$promise->resolve($value);","typeGuard":"function isSelfReference(\\GuzzleHttp\\Promise\\Promise $p, $value): bool\n{\n    return $value === $p;\n}","tryCatchPattern":"try {\n    $promise->resolve($value);\n} catch (\\LogicException $e) {\n    // self-settlement cycle; return/chain the promise instead\n}","preventionTips":["In pass-through functions, return the promise instead of resolving it with itself.","Never reference $this inside a promise's own wait/resolver function as the settling value.","Add an assertion $value !== $this in custom PromiseInterface implementations."],"tags":["promises","self-reference","guzzle"],"backgroundTag":"internal-invariant-violation","analyzedSha":"42118e66a53c492effaf92bc357e931985d5c6f9","analyzedAt":"2026-09-14T00:10:14.865Z","contentChangedAt":"2026-09-14T00:10:14.865Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}