python/cpython · error · RuntimeError

Task does not support set_result operation

Error message

Task does not support set_result operation

What it means

RuntimeError raised by Task.set_result(): Task inherits from Future but its result is determined solely by driving the wrapped coroutine, so manually resolving it is forbidden. Any generic 'complete this future' code path that receives a Task hits this immediately.

Source

Thrown at Lib/asyncio/tasks.py:144

    __class_getitem__ = classmethod(GenericAlias)

    def __repr__(self):
        return base_tasks._task_repr(self)

    def get_coro(self):
        return self._coro

    def get_context(self):
        return self._context

    def get_name(self):
        return self._name

    def set_name(self, value):
        self._name = str(value)

    def set_result(self, result):
        raise RuntimeError('Task does not support set_result operation')

    def set_exception(self, exception):
        raise RuntimeError('Task does not support set_exception operation')

    def get_stack(self, *, limit=None):
        """Return the list of stack frames for this task's coroutine.

        If the coroutine is not done, this returns the stack where it is
        suspended.  If the coroutine has completed successfully or was
        cancelled, this returns an empty list.  If the coroutine was
        terminated by an exception, this returns the list of traceback
        frames.

        The frames are always ordered from oldest to newest.

        The optional limit gives the maximum number of frames to
        return; by default all available frames are returned.  Its
        meaning differs depending on whether a stack or a traceback is

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Use loop.create_future() for manually completed synchronization primitives; keep Tasks only for scheduled coroutines
  2. Change generic completion helpers to call loop.call_soon_threadsafe(fut.set_result, ...) on a Future they created themselves
  3. If you need to deliver a value to a Task, feed it via a queue, event, or future the task awaits

Example fix

// before
wakeup = asyncio.create_task(wait_and_process())
loop.call_soon_threadsafe(wakeup.set_result, data)  # RuntimeError

// after
wakeup = loop.create_future()
loop.call_soon_threadsafe(wakeup.set_result, data)
data = await wakeup  # consumed by the coroutine that needs it
Defensive patterns

Strategy: validation

Validate before calling

null

Type guard

import asyncio

def is_completable_future(f) -> bool:
    return isinstance(f, asyncio.Future) and not isinstance(f, asyncio.Task)

Try / catch

null

Prevention

When it happens

Trigger: Calling task.set_result(value) directly; a helper written against futures (e.g. a waiter registry, timeout helper, or thread-bridge using loop.call_soon_threadsafe(fut.set_result, x)) that was handed a Task instead of a plain Future.

Common situations: Waiter maps that store whatever create_future/ensure_future returned; mixing Task and Future in the same synchronization structure; adapting threading code where 'set the result' is the normal completion idiom; wake-up signals between a protocol and its consumer implemented with futures.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/4d311eaea84db0aa. Report an issue: GitHub.