{"record":{"id":"68bbbf7572c546a4","repo":"JuliusBrussee/caveman","slug":"bind-runtime-key-r-with-caveman-middleware-autogen-component","errorCode":null,"errorMessage":"Bind runtime {key!r} with caveman_middleware.autogen.component_runtimes before loading","messagePattern":"Bind runtime (.+?) with caveman_middleware\\.autogen\\.component_runtimes before loading","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"packages/middleware/python/caveman_middleware/autogen.py","lineNumber":66,"sourceCode":"    Configurations store a reference key, never runtime credentials. Loading a\n    key requires this explicit application-owned binding; the key grants no\n    authority by itself. Nested contexts restore the previous bindings.\n    \"\"\"\n    token = _component_runtimes.set({**_component_runtimes.get(), **runtimes})\n    loaded = []\n    resources = _loaded_components.set(loaded)\n    try:\n        yield loaded\n    finally:\n        _loaded_components.reset(resources)\n        _component_runtimes.reset(token)\n\n\ndef _runtime(key):\n    try:\n        return _component_runtimes.get()[key]\n    except KeyError:\n        raise ValueError(f\"Bind runtime {key!r} with caveman_middleware.autogen.component_runtimes before loading\") from None\n\n\ndef _supported(runtime):\n    return supports_framework(runtime, (\"autogen-core\", \"0.7\", \"0.8\"), (\"autogen-agentchat\", \"0.7\", \"0.8\"), (\"autogen-ext\", \"0.7\", \"0.8\"))\n\n\ndef _version_supported():\n    return matches_framework((\"autogen-core\", \"0.7\", \"0.8\"), (\"autogen-agentchat\", \"0.7\", \"0.8\"), (\"autogen-ext\", \"0.7\", \"0.8\"))\n\n\ndef _check(runtime, scope):\n    if not isinstance(scope, Scope):\n        raise TypeError(\"AutoGen requires a stable Caveman Scope for each agent or model context\")\n    return runtime.as_async() if isinstance(runtime, MiddlewareRuntime) else runtime\n\n\ndef _schema():\n    parameters = copy.deepcopy(RECOVERY_SCHEMA)","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/middleware/python/caveman_middleware/autogen.py#L48-L84","documentation":"The AutoGen adapter resolves its MiddlewareRuntime lazily from a ContextVar registry (caveman_middleware.autogen.component_runtimes) keyed by string. When AutoGen deserializes a component from config (component_config), the adapter's _from_config calls _runtime(key), and if no runtime was bound under that key before loading, this ValueError is raised. It exists so runtime objects (which are not serializable) can be re-attached after config-based component loading.","triggerScenarios":"Loading an AutoGen component (e.g. via ChatCompletionClient.load_component(...) or Workbench.load_component) from a serialized config whose caveman runtime key was never registered via the component_runtimes context manager; a typo'd/mismatched key between bind and load; binding in a different task/async context so the ContextVar is not visible; deserializing in a fresh process (worker restart, CI, notebook) where only JSON config exists.","commonSituations":"AutoGen apps that serialize components to YAML/JSON for deployment; key changed after refactor but old serialized configs still reference it; binding done at module top-level in one file while load happens inside a different asyncio task where the context var did not propagate.","solutions":["Wrap the load call in `with caveman_middleware.autogen.component_runtimes({'<key>': runtime}):` using the exact key from the component config","Print/inspect the component config to find the expected key and make the bind key match exactly (it is case-sensitive)","Perform the bind inside the same coroutine/task that performs the load so the ContextVar is visible (contextvars do not cross task boundaries automatically)","Re-bind the runtime after process restart before calling load_component; config files alone cannot restore a runtime"],"exampleFix":"// before\nclient = ChatCompletionClient.load_component(cfg)  # ValueError: Bind runtime 'main' ...\n// after\nimport caveman_middleware.autogen as cm_autogen\nwith cm_autogen.component_runtimes({'main': runtime}):\n    client = ChatCompletionClient.load_component(cfg)","handlingStrategy":"try-catch","validationCode":"from caveman_middleware.autogen import component_runtimes\nkey = cfg.get('component_type') and extract_runtime_key(cfg)  # your config's runtime key\nassert key in _known_bound_keys, f'bind runtime {key!r} via component_runtimes before load'","typeGuard":null,"tryCatchPattern":"try:\n    with component_runtimes({'main': runtime}):\n        client = ChatCompletionClient.load_component(cfg)\nexcept ValueError as e:\n    if str(e).startswith('Bind runtime'):\n        logging.error('runtime key missing at load: %s', e)\n    raise","preventionTips":["Bind the runtime with component_runtimes in the same task/coroutine that calls load_component","Keep the runtime key constant next to the serialization code so config and bind stay in sync","After any worker restart, always re-bind before deserializing components; config alone is not enough"],"tags":["python","autogen","configuration","contextvar","deserialization"],"backgroundTag":"missing-config-key","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}