cocoindex-io/cocoindex · error · RuntimeError

No ComponentContext available. This function must be called

Error message

No ComponentContext available. This function must be called from within an active component context (inside a mount/use_mount call or App.update).

What it means

get_context_from_ctx() fetches the ambient ComponentContext from a ContextVar that is only set while a component is executing (inside mount/use_mount or App.update). Called outside such a scope there is no context, and the function raises RuntimeError explaining where the call is valid.

Source

Thrown at python/cocoindex/_internal/component_ctx.py:356

        ExceptionHandlerChain(handler=env.exception_handler)
        if env.exception_handler
        else None
    )
    context = ComponentContext(env, path, comp_ctx, fn_ctx, base_chain)
    tok = _context_var.set(context)
    try:
        yield
    finally:
        _context_var.reset(tok)
        comp_ctx.join_fn_call(fn_ctx)


def get_context_from_ctx() -> ComponentContext:
    """Get the current ComponentContext from ContextVar."""
    ctx_var = _context_var.get(None)
    if ctx_var is not None:
        return ctx_var
    raise RuntimeError(
        "No ComponentContext available. This function must be called from within "
        "an active component context (inside a mount/use_mount call or App.update)."
    )


def build_child_path(
    parent_ctx: ComponentContext, subpath: ComponentSubpath
) -> core.StablePath:
    """Build the child path from parent context and subpath."""
    child_path = parent_ctx._core_path
    for part in subpath.parts:
        child_path = child_path.concat(part)
    return child_path


def use_context(key: ContextKey[T]) -> T:
    """
    Retrieve a value from the context.

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Call the API from inside a mounted component body (function passed to mount/use_mount/mount_each) or during App.update
  2. For threads, grab ctx = coco.get_component_context() in the component and wrap thread work in `with ctx.attach():`
  3. For background work, keep it within the component's async scope (e.g. create tasks from inside the component rather than after it)

Example fix

// before
db = coco.use_context(PG_DB)  # module level -> RuntimeError
// after
@coco.fn
async def app_main(...):
    db = coco.use_context(PG_DB)
Defensive patterns

Strategy: type-guard

Validate before calling

import cocoindex as coco

def has_component_ctx() -> bool:
    try:
        coco.get_component_context()
        return True
    except RuntimeError:
        return False

Type guard

def in_component_context() -> bool:
    try:
        coco.get_component_context()
        return True
    except RuntimeError:
        return False

Try / catch

try:
    db = coco.use_context(PG_DB)
except RuntimeError as e:
    if "No ComponentContext available" in str(e):
        raise  # move the call inside a mounted component / attach ctx in threads

Prevention

When it happens

Trigger: Calling context-dependent APIs (coco.use_context, coco.use_state, nested mount/use_mount, get_context_from_ctx) from module top level, plain functions outside a mounted component, a background thread without ctx.attach(), or after the component finished.

Common situations: Calling coco.use_context() at import time; running coco APIs in a ThreadPoolExecutor without attaching the component context; invoking helpers from tests outside an App.update; fire-and-forget tasks that outlive the component.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/232a7222b0594841. Report an issue: GitHub.