Nicer warnings when config: dict is used (and not injected) #885

Closed
opened 2026-02-20 17:42:14 -05:00 by yindo · 1 comment
Owner

Originally created by @sydney-runkle on GitHub (Jul 31, 2025).

Originally assigned to: @sydney-runkle on GitHub.

config should always be typed as one of RunnableConfig or Optional[RunnableConfig].

Investigate the logic in _utils/_runnable.py. If config is present in the signature but typed as dict or not one of the allowed values, we should raise a helpful warning.

Please add a test for this in test_deprecation.py

Here's an example of code that doesn't work well:

from typing import Dict, List

from langchain_core.messages import AIMessage
from langgraph.graph import StateGraph
import asyncio
from typing_extensions import TypedDict

from langgraph.version import __version__ as version


class State(TypedDict):
    foo: str


async def call_model(state: State, config: dict) -> Dict[str, List[AIMessage]]:
    print("CONFIG", config)
    return {"foo": "bar"}


builder = StateGraph(State)
builder.add_node(call_model)
builder.add_edge("__start__", "call_model")
graph = builder.compile(name="ReAct Agent")


async def main():
    async for chunk in graph.astream(
        {
            "messages": [{"role": "user", "content": "Hi there!"}],
            "configurable": {"foo": "bar"},
        }
    ):
        pass


try:
    asyncio.run(main())
    print(f"Passed in langgraph version=={version}")
except Exception as e:
    print(f"Failed in langgraph version=={version}")
    print("ERROR", e)

Ideally we would talk update the files in the examples directory to use updated syntax as well.

Agent Context { "tasks": [ { "id": "8ed7d1e7-a6f7-41e6-9df8-53336631eba5", "taskIndex": 0, "request": "[original issue]\n**Nicer warnings when `config: dict` is used (and not injected)**\n`config` should always be typed as one of `RunnableConfig` or `Optional[RunnableConfig]`.\n\nInvestigate the logic in `_utils/_runnable.py`. If `config` is present in the signature but typed as `dict` or not one of the allowed values, we should raise a helpful warning.\n\nPlease add a test for this in `test_deprecation.py`\n\nHere's an example of code that doesn't work well:\n\n```py\nfrom typing import Dict, List\n\nfrom langchain_core.messages import AIMessage\nfrom langgraph.graph import StateGraph\nimport asyncio\nfrom typing_extensions import TypedDict\n\nfrom langgraph.version import __version__ as version\n\n\nclass State(TypedDict):\n foo: str\n\n\nasync def call_model(state: State, config: dict) -> Dict[str, List[AIMessage]]:\n print(\"CONFIG\", config)\n return {\"foo\": \"bar\"}\n\n\nbuilder = StateGraph(State)\nbuilder.add_node(call_model)\nbuilder.add_edge(\"__start__\", \"call_model\")\ngraph = builder.compile(name=\"ReAct Agent\")\n\n\nasync def main():\n async for chunk in graph.astream(\n {\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi there!\"}],\n \"configurable\": {\"foo\": \"bar\"},\n }\n ):\n pass\n\n\ntry:\n asyncio.run(main())\n print(f\"Passed in langgraph version=={version}\")\nexcept Exception as e:\n print(f\"Failed in langgraph version=={version}\")\n print(\"ERROR\", e)\n```\n\nIdeally we would talk update the files in the `examples` directory to use updated syntax as well. ", "title": "Add warning for incorrect config parameter typing in LangGraph", "createdAt": 1754059664155, "completed": false, "planRevisions": [ { "revisionIndex": 0, "plans": [ { "index": 0, "plan": "**Implement warning for incorrect config parameter typing in RunnableCallable**\n\nModify `/home/daytona/langgraph/libs/langgraph/langgraph/_internal/_runnable.py` to add a warning when a `config` parameter is present in a function signature but typed as `dict` or any other incorrect type. The warning should be added in the `RunnableCallable.__init__` method after line 303 where it checks if the annotation matches the expected types. Import the `LangGraphDeprecatedSinceV10` warning class from `langgraph.warnings` and emit a helpful warning message explaining that `config` should be typed as `RunnableConfig` or `Optional[RunnableConfig]`.", "completed": true, "summary": "Successfully implemented warning for incorrect config parameter typing in RunnableCallable.\n\nChanges made to `/home/daytona/langgraph/libs/langgraph/langgraph/_internal/_runnable.py`:\n1. Added import for `warnings` module at line 6\n2. Added import for `LangGraphDeprecatedSinceV10` from `langgraph.warnings` at line 58\n3. Added warning logic in the `RunnableCallable.__init__` method (lines 309-316) that:\n - Checks if the parameter is named \"config\" and has an annotation that's not empty\n - Emits a `LangGraphDeprecatedSinceV10` warning with a clear message explaining the correct typing\n - The warning message states: \"The 'config' parameter should be typed as 'RunnableConfig' or 'Optional[RunnableConfig]', not '{p.annotation}'. The config will not be injected automatically when typed incorrectly\"\n - Uses stacklevel=2 to ensure the warning points to the user's code\n\nThe implementation correctly handles the case where a function has a `config` parameter with incorrect typing (like `dict`) and warns the user about the issue while explaining the correct approach." }, { "index": 1, "plan": "**Add test for config parameter warning in test_deprecation.py**\n\nAdd a new test function to `/home/daytona/langgraph/libs/langgraph/tests/test_deprecation.py` that verifies the warning is raised when a function has a `config` parameter typed as `dict`. The test should:\n- Create a function with `config: dict` parameter\n- Use `pytest.warns` to check that `LangGraphDeprecatedSinceV10` is raised with an appropriate message\n- Test both sync and async functions\n- Verify that no warning is raised when config is typed correctly as `RunnableConfig` or `Optional[RunnableConfig]`", "completed": true, "summary": "Added a comprehensive test to `/home/daytona/langgraph/libs/langgraph/tests/test_deprecation.py` that verifies the warning is raised when a function has a `config` parameter typed as `dict` or other incorrect types. The test:\n- Uses `pytest.warns` to check that `LangGraphDeprecatedSinceV10` is raised with the correct message for both sync and async functions with `config: dict` and `config: str`.\n- Verifies that no warning is raised when `config` is typed as `RunnableConfig` or `Optional[RunnableConfig]` (including for async functions).\n- Ensures the warning message is clear and matches the expected pattern.\n\nThis test ensures the new warning logic is robust and covers all relevant cases." }, { "index": 2, "plan": "**Run tests and formatters**\n\nNavigate to `/home/daytona/langgraph/libs/langgraph` and run:\n- `make format` to format the code\n- `make lint` to check for linting issues\n- `TEST=tests/test_deprecation.py make test` to run the specific test file and ensure the new test passes", "completed": true, "summary": "Successfully ran all required tests and formatters in `/home/daytona/langgraph/libs/langgraph`:\n\n1. **make format**: Reformatted 2 files and fixed 1 import issue. The formatter automatically corrected import ordering.\n\n2. **make lint**: All linting checks passed successfully:\n - ruff check passed\n - ruff format check showed all 105 files already formatted\n - ruff import check passed\n - mypy type checking found no issues in 64 source files\n\n3. **TEST=tests/test_deprecation.py make test**: Successfully ran the test file with all 16 tests passing, including the newly added `test_config_parameter_incorrect_typing()` test.\n\nThe new warning implementation and test are working correctly, and the code meets all quality standards." } ], "createdAt": 1754059664155, "createdBy": "agent" } ], "activeRevisionIndex": 0, "pullRequestNumber": 5798 } ], "activeTaskIndex": 0 }
Originally created by @sydney-runkle on GitHub (Jul 31, 2025). Originally assigned to: @sydney-runkle on GitHub. `config` should always be typed as one of `RunnableConfig` or `Optional[RunnableConfig]`. Investigate the logic in `_utils/_runnable.py`. If `config` is present in the signature but typed as `dict` or not one of the allowed values, we should raise a helpful warning. Please add a test for this in `test_deprecation.py` Here's an example of code that doesn't work well: ```py from typing import Dict, List from langchain_core.messages import AIMessage from langgraph.graph import StateGraph import asyncio from typing_extensions import TypedDict from langgraph.version import __version__ as version class State(TypedDict): foo: str async def call_model(state: State, config: dict) -> Dict[str, List[AIMessage]]: print("CONFIG", config) return {"foo": "bar"} builder = StateGraph(State) builder.add_node(call_model) builder.add_edge("__start__", "call_model") graph = builder.compile(name="ReAct Agent") async def main(): async for chunk in graph.astream( { "messages": [{"role": "user", "content": "Hi there!"}], "configurable": {"foo": "bar"}, } ): pass try: asyncio.run(main()) print(f"Passed in langgraph version=={version}") except Exception as e: print(f"Failed in langgraph version=={version}") print("ERROR", e) ``` Ideally we would talk update the files in the `examples` directory to use updated syntax as well. <details> <summary>Agent Context</summary> <open-swe-do-not-edit-task-plan> { "tasks": [ { "id": "8ed7d1e7-a6f7-41e6-9df8-53336631eba5", "taskIndex": 0, "request": "[original issue]\n**Nicer warnings when `config: dict` is used (and not injected)**\n`config` should always be typed as one of `RunnableConfig` or `Optional[RunnableConfig]`.\n\nInvestigate the logic in `_utils/_runnable.py`. If `config` is present in the signature but typed as `dict` or not one of the allowed values, we should raise a helpful warning.\n\nPlease add a test for this in `test_deprecation.py`\n\nHere's an example of code that doesn't work well:\n\n```py\nfrom typing import Dict, List\n\nfrom langchain_core.messages import AIMessage\nfrom langgraph.graph import StateGraph\nimport asyncio\nfrom typing_extensions import TypedDict\n\nfrom langgraph.version import __version__ as version\n\n\nclass State(TypedDict):\n foo: str\n\n\nasync def call_model(state: State, config: dict) -> Dict[str, List[AIMessage]]:\n print(\"CONFIG\", config)\n return {\"foo\": \"bar\"}\n\n\nbuilder = StateGraph(State)\nbuilder.add_node(call_model)\nbuilder.add_edge(\"__start__\", \"call_model\")\ngraph = builder.compile(name=\"ReAct Agent\")\n\n\nasync def main():\n async for chunk in graph.astream(\n {\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi there!\"}],\n \"configurable\": {\"foo\": \"bar\"},\n }\n ):\n pass\n\n\ntry:\n asyncio.run(main())\n print(f\"Passed in langgraph version=={version}\")\nexcept Exception as e:\n print(f\"Failed in langgraph version=={version}\")\n print(\"ERROR\", e)\n```\n\nIdeally we would talk update the files in the `examples` directory to use updated syntax as well. ", "title": "Add warning for incorrect config parameter typing in LangGraph", "createdAt": 1754059664155, "completed": false, "planRevisions": [ { "revisionIndex": 0, "plans": [ { "index": 0, "plan": "**Implement warning for incorrect config parameter typing in RunnableCallable**\n\nModify `/home/daytona/langgraph/libs/langgraph/langgraph/_internal/_runnable.py` to add a warning when a `config` parameter is present in a function signature but typed as `dict` or any other incorrect type. The warning should be added in the `RunnableCallable.__init__` method after line 303 where it checks if the annotation matches the expected types. Import the `LangGraphDeprecatedSinceV10` warning class from `langgraph.warnings` and emit a helpful warning message explaining that `config` should be typed as `RunnableConfig` or `Optional[RunnableConfig]`.", "completed": true, "summary": "Successfully implemented warning for incorrect config parameter typing in RunnableCallable.\n\nChanges made to `/home/daytona/langgraph/libs/langgraph/langgraph/_internal/_runnable.py`:\n1. Added import for `warnings` module at line 6\n2. Added import for `LangGraphDeprecatedSinceV10` from `langgraph.warnings` at line 58\n3. Added warning logic in the `RunnableCallable.__init__` method (lines 309-316) that:\n - Checks if the parameter is named \"config\" and has an annotation that's not empty\n - Emits a `LangGraphDeprecatedSinceV10` warning with a clear message explaining the correct typing\n - The warning message states: \"The 'config' parameter should be typed as 'RunnableConfig' or 'Optional[RunnableConfig]', not '{p.annotation}'. The config will not be injected automatically when typed incorrectly\"\n - Uses stacklevel=2 to ensure the warning points to the user's code\n\nThe implementation correctly handles the case where a function has a `config` parameter with incorrect typing (like `dict`) and warns the user about the issue while explaining the correct approach." }, { "index": 1, "plan": "**Add test for config parameter warning in test_deprecation.py**\n\nAdd a new test function to `/home/daytona/langgraph/libs/langgraph/tests/test_deprecation.py` that verifies the warning is raised when a function has a `config` parameter typed as `dict`. The test should:\n- Create a function with `config: dict` parameter\n- Use `pytest.warns` to check that `LangGraphDeprecatedSinceV10` is raised with an appropriate message\n- Test both sync and async functions\n- Verify that no warning is raised when config is typed correctly as `RunnableConfig` or `Optional[RunnableConfig]`", "completed": true, "summary": "Added a comprehensive test to `/home/daytona/langgraph/libs/langgraph/tests/test_deprecation.py` that verifies the warning is raised when a function has a `config` parameter typed as `dict` or other incorrect types. The test:\n- Uses `pytest.warns` to check that `LangGraphDeprecatedSinceV10` is raised with the correct message for both sync and async functions with `config: dict` and `config: str`.\n- Verifies that no warning is raised when `config` is typed as `RunnableConfig` or `Optional[RunnableConfig]` (including for async functions).\n- Ensures the warning message is clear and matches the expected pattern.\n\nThis test ensures the new warning logic is robust and covers all relevant cases." }, { "index": 2, "plan": "**Run tests and formatters**\n\nNavigate to `/home/daytona/langgraph/libs/langgraph` and run:\n- `make format` to format the code\n- `make lint` to check for linting issues\n- `TEST=tests/test_deprecation.py make test` to run the specific test file and ensure the new test passes", "completed": true, "summary": "Successfully ran all required tests and formatters in `/home/daytona/langgraph/libs/langgraph`:\n\n1. **make format**: Reformatted 2 files and fixed 1 import issue. The formatter automatically corrected import ordering.\n\n2. **make lint**: All linting checks passed successfully:\n - ruff check passed\n - ruff format check showed all 105 files already formatted\n - ruff import check passed\n - mypy type checking found no issues in 64 source files\n\n3. **TEST=tests/test_deprecation.py make test**: Successfully ran the test file with all 16 tests passing, including the newly added `test_config_parameter_incorrect_typing()` test.\n\nThe new warning implementation and test are working correctly, and the code meets all quality standards." } ], "createdAt": 1754059664155, "createdBy": "agent" } ], "activeRevisionIndex": 0, "pullRequestNumber": 5798 } ], "activeTaskIndex": 0 } </open-swe-do-not-edit-task-plan> </details>
yindo added the open-swe-max-auto label 2026-02-20 17:42:14 -05:00
yindo closed this issue 2026-02-20 17:42:14 -05:00
Author
Owner

@open-swe[bot] commented on GitHub (Aug 1, 2025):

🤖 Open SWE has been triggered for this issue. Processing...

View run in Open SWE here (this URL will only work for @sydney-runkle)

Dev Metadata { "runId": "1f06ee57-786d-6cf2-8d57-7990ed137c46", "threadId": "b8e586ff-5755-4287-ba83-60061193aeab" }

🤖 Plan Generated

I've generated a plan for this issue and will proceed to implement it since auto-accept is enabled.

Plan: Add warning for incorrect config parameter typing in LangGraph

  • Task 1:
**Implement warning for incorrect config parameter typing in RunnableCallable**

Modify `/home/daytona/langgraph/libs/langgraph/langgraph/_internal/_runnable.py` to add a warning when a `config` parameter is present in a function signature but typed as `dict` or any other incorrect type. The warning should be added in the `RunnableCallable.__init__` method after line 303 where it checks if the annotation matches the expected types. Import the `LangGraphDeprecatedSinceV10` warning class from `langgraph.warnings` and emit a helpful warning message explaining that `config` should be typed as `RunnableConfig` or `Optional[RunnableConfig]`.
  • Task 2:
**Add test for config parameter warning in test_deprecation.py**

Add a new test function to `/home/daytona/langgraph/libs/langgraph/tests/test_deprecation.py` that verifies the warning is raised when a function has a `config` parameter typed as `dict`. The test should:
- Create a function with `config: dict` parameter
- Use `pytest.warns` to check that `LangGraphDeprecatedSinceV10` is raised with an appropriate message
- Test both sync and async functions
- Verify that no warning is raised when config is typed correctly as `RunnableConfig` or `Optional[RunnableConfig]`
  • Task 3:
**Run tests and formatters**

Navigate to `/home/daytona/langgraph/libs/langgraph` and run:
- `make format` to format the code
- `make lint` to check for linting issues
- `TEST=tests/test_deprecation.py make test` to run the specific test file and ensure the new test passes

Proceeding to implementation...

@open-swe[bot] commented on GitHub (Aug 1, 2025): 🤖 Open SWE has been triggered for this issue. Processing... View run in Open SWE [here](https://swe.langchain.com/chat/b8e586ff-5755-4287-ba83-60061193aeab) (this URL will only work for @sydney-runkle) <details> <summary>Dev Metadata</summary> { "runId": "1f06ee57-786d-6cf2-8d57-7990ed137c46", "threadId": "b8e586ff-5755-4287-ba83-60061193aeab" } </details> <open-swe-plan-message> ### 🤖 Plan Generated I've generated a plan for this issue and will proceed to implement it since auto-accept is enabled. **Plan: Add warning for incorrect config parameter typing in LangGraph** - Task 1: ``` **Implement warning for incorrect config parameter typing in RunnableCallable** Modify `/home/daytona/langgraph/libs/langgraph/langgraph/_internal/_runnable.py` to add a warning when a `config` parameter is present in a function signature but typed as `dict` or any other incorrect type. The warning should be added in the `RunnableCallable.__init__` method after line 303 where it checks if the annotation matches the expected types. Import the `LangGraphDeprecatedSinceV10` warning class from `langgraph.warnings` and emit a helpful warning message explaining that `config` should be typed as `RunnableConfig` or `Optional[RunnableConfig]`. ``` - Task 2: ``` **Add test for config parameter warning in test_deprecation.py** Add a new test function to `/home/daytona/langgraph/libs/langgraph/tests/test_deprecation.py` that verifies the warning is raised when a function has a `config` parameter typed as `dict`. The test should: - Create a function with `config: dict` parameter - Use `pytest.warns` to check that `LangGraphDeprecatedSinceV10` is raised with an appropriate message - Test both sync and async functions - Verify that no warning is raised when config is typed correctly as `RunnableConfig` or `Optional[RunnableConfig]` ``` - Task 3: ``` **Run tests and formatters** Navigate to `/home/daytona/langgraph/libs/langgraph` and run: - `make format` to format the code - `make lint` to check for linting issues - `TEST=tests/test_deprecation.py make test` to run the specific test file and ensure the new test passes ``` Proceeding to implementation... </open-swe-plan-message>
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#885