{"record":{"id":"ff9571476c9cb3c7","repo":"guzzle/promises","slug":"you-cannot-create-a-fulfilledpromise-with-a-promise","errorCode":null,"errorMessage":"You cannot create a FulfilledPromise with a promise.","messagePattern":"You cannot create a FulfilledPromise with a promise\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/FulfilledPromise.php","lineNumber":31,"sourceCode":" * @template TValue = mixed\n * @template TReason = never\n *\n * @implements PromiseInterface<TValue, TReason>\n *\n * @final\n */\nclass FulfilledPromise implements PromiseInterface\n{\n    /** @var TValue */\n    private $value;\n\n    /**\n     * @param TValue $value\n     */\n    public function __construct($value)\n    {\n        if (is_object($value) && method_exists($value, 'then')) {\n            throw new \\InvalidArgumentException(\n                'You cannot create a FulfilledPromise with a promise.'\n            );\n        }\n\n        $this->value = $value;\n    }\n\n    /**\n     * @template TFulfilledValue = never\n     * @template TFulfilledReason = never\n     * @template TRejectedValue = never\n     * @template TRejectedReason = never\n     *\n     * @param (callable(TValue): (TFulfilledValue|PromiseInterface<TFulfilledValue, TFulfilledReason>))|null $onFulfilled Invoked when the promise fulfills.\n     * @param (callable(TReason): (TRejectedValue|PromiseInterface<TRejectedValue, TRejectedReason>))|null   $onRejected  Invoked when the promise is rejected.\n     *\n     * @return ($onFulfilled is null ? self<TValue, TReason> : PromiseInterface<TFulfilledValue, TFulfilledReason|\\Throwable>)\n     */","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/guzzle/promises/blob/42118e66a53c492effaf92bc357e931985d5c6f9/src/FulfilledPromise.php#L13-L49","documentation":"A FulfilledPromise represents an already-known fulfilled value, so its constructor rejects any object exposing a then() method (a promise or thenable). Wrapping a promise inside a fulfilled promise would create a promise-of-a-promise, which this library's unwrapping semantics cannot represent. Unwrap the promise to its concrete value first.","triggerScenarios":"new FulfilledPromise($x) where $x is any object with a then() method, e.g. another FulfilledPromise, RejectedPromise, Promise, PromiseInterface implementation, or foreign thenable.","commonSituations":"Passing an unresolved promise into code that expects a plain value; converting from another promise library; double-wrapping results of queue()->run() or coroutines; caching layers that wrap values indiscriminately.","solutions":["Resolve the inner promise first: pass $promise->wait() to FulfilledPromise.","Use \\GuzzleHttp\\Promise\\resolve($promise) which unwraps thenables into a settled promise instead of constructing manually.","If the intent was conditional settling, create a new Promise() and call resolve()/reject() on it with the inner outcome.","Type-check inputs before construction and reject promises early in your own API."],"exampleFix":"// before\n$wrapped = new FulfilledPromise($innerPromise); // InvalidArgumentException\n// after\n$wrapped = \\GuzzleHttp\\Promise\\resolve($innerPromise->wait());","handlingStrategy":"type-guard","validationCode":"if (is_object($value) && method_exists($value, 'then')) {\n    throw new \\InvalidArgumentException('Value must not be a promise/thenable');\n}","typeGuard":"function assertNotThenable($value): void\n{\n    if (is_object($value) && method_exists($value, 'then')) {\n        throw new \\InvalidArgumentException('Cannot wrap a promise; unwrap it first.');\n    }\n}","tryCatchPattern":"try {\n    $p = new \\GuzzleHttp\\Promise\\FulfilledPromise($value);\n} catch (\\InvalidArgumentException $e) {\n    $p = \\GuzzleHttp\\Promise\\resolve($value); // unwraps thenables\n}","preventionTips":["Never construct FulfilledPromise directly from values of unknown origin; use \\GuzzleHttp\\Promise\\resolve() which handles thenables.","Keep functions that consume values separate from those that consume promises.","Check method_exists($v, 'then') before wrapping third-party objects."],"tags":["promises","constructor","type-mismatch","guzzle"],"backgroundTag":"invalid-constructor-argument","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"}