From 326fd55e4f29a6b2d8127f416410bcd21efe2643 Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Wed, 10 Sep 2025 08:19:33 -0400 Subject: [PATCH] fix(langgraph): key error on runtime for config w/o configurable (#6106) Fixes https://github.com/langchain-ai/langgraph/issues/6072 Long term we probably want a more robust approach to configurable management in terms of required / not required attributes. --- .../langgraph/langgraph/_internal/_runnable.py | 4 ++-- libs/langgraph/tests/test_runnable.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libs/langgraph/langgraph/_internal/_runnable.py b/libs/langgraph/langgraph/_internal/_runnable.py index 82db24e92..f4bce0b2a 100644 --- a/libs/langgraph/langgraph/_internal/_runnable.py +++ b/libs/langgraph/langgraph/_internal/_runnable.py @@ -345,7 +345,7 @@ class RunnableCallable(Runnable): args = (input,) kwargs = {**self.kwargs, **kwargs} - runtime = config[CONF].get(CONFIG_KEY_RUNTIME) + runtime = config.get(CONF, {}).get(CONFIG_KEY_RUNTIME) for kw, (runtime_key, default) in self.func_accepts.items(): # If the kwarg is already set, use the set value @@ -417,7 +417,7 @@ class RunnableCallable(Runnable): args = (input,) kwargs = {**self.kwargs, **kwargs} - runtime = config[CONF].get(CONFIG_KEY_RUNTIME) + runtime = config.get(CONF, {}).get(CONFIG_KEY_RUNTIME) for kw, (runtime_key, default) in self.func_accepts.items(): # If the kwarg has already been set, use the set value diff --git a/libs/langgraph/tests/test_runnable.py b/libs/langgraph/tests/test_runnable.py index b7b85f894..35eb53c1c 100644 --- a/libs/langgraph/tests/test_runnable.py +++ b/libs/langgraph/tests/test_runnable.py @@ -394,3 +394,21 @@ def test_config_injection() -> None: assert RunnableCallable(func_untyped).invoke( "test", config={"tags": ["test"], "configurable": {}} ) == ["test"] + + +def test_config_ensured() -> None: + def func(input: str, config: RunnableConfig) -> None: + assert input == "test" + assert config is not None + assert config.get("configurable") is not None + + RunnableCallable(func).invoke("test") + + +async def test_config_ensured_async() -> None: + async def func(input: str, config: RunnableConfig) -> None: + assert input == "test" + assert config is not None + assert config.get("configurable") is not None + + await RunnableCallable(func).ainvoke("test")