Human in the loop: Validating human input - while loop example repeated based on number of invocation #556

Closed
opened 2026-02-20 17:40:42 -05:00 by yindo · 3 comments
Owner

Originally created by @arindam-b on GitHub (Apr 4, 2025).

Originally assigned to: @eyurtsev on GitHub.

Checked other resources

  • This is a bug, not a usage question. For questions, please use GitHub Discussions.
  • I added a clear and detailed title that summarizes the issue.
  • I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
  • I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.

Example Code

from langgraph.types import interrupt

def human_node(state: State):
    """Human node with validation."""
    question = "What is your age?"

    while True:
        answer = interrupt(question)

        # Validate answer, if the answer isn't valid ask for input again.
        if not isinstance(answer, int) or answer < 0:
            question = f"'{answer} is not a valid age. What is your age?"
            answer = None
            continue
        else:
            # If the answer is valid, we can proceed.
            break

    print(f"The human in the loop is {answer} years old.")
    return {
        "age": answer
    }

Error Message and Stack Trace (if applicable)


Description

The above example is taken from the url: https://langchain-ai.github.io/langgraph/concepts/human_in_the_loop/#validating-human-input

The while loop breaks if the condition is not met. So the loop continues till the user is satisfied with the response.

However, when the first human_node is called, it runs smoothly. But it is called second time, this blocks called twice. So, as many times as the question is asked, every time that is called that many times.

For example, if the loop condition is satisfied to continue, the first time the logic will execute just once.
But the second time, it will be executed precisely twice and third time, thrice.

This can be overcome by another human_node for example, human_node_2 which checks the response and redirects the flow using a goto command, something like the following:


return Command(
	    goto="check_continue_human_node",  # The next node(s) to go to
	    update={"ai_responses": [response]}  # The update to apply to the state
	  )

System Info

System Information

OS: Linux
OS Version: #1 SMP PREEMPT_DYNAMIC Thu Jun 27 21:05:47 UTC 2024
Python Version: 3.11.11 (main, Dec 4 2024, 08:55:07) [GCC 11.4.0]

Package Information

langchain_core: 0.3.50
langchain: 0.3.22
langchain_community: 0.3.20
langsmith: 0.3.22
langchain_aws: 0.2.18
langchain_postgres: 0.0.13
langchain_text_splitters: 0.3.7
langgraph_sdk: 0.1.61

Optional packages not installed

langserve

Other Dependencies

aiohttp<4.0.0,>=3.8.3: Installed. No version info available.
async-timeout<5.0.0,>=4.0.0;: Installed. No version info available.
boto3: 1.37.27
dataclasses-json<0.7,>=0.5.7: Installed. No version info available.
httpx: 0.28.1
httpx-sse<1.0.0,>=0.4.0: Installed. No version info available.
jsonpatch<2.0,>=1.33: Installed. No version info available.
langchain-anthropic;: Installed. No version info available.
langchain-aws;: Installed. No version info available.
langchain-azure-ai;: Installed. No version info available.
langchain-cohere;: Installed. No version info available.
langchain-community;: Installed. No version info available.
langchain-core<1.0.0,>=0.3.45: Installed. No version info available.
langchain-core<1.0.0,>=0.3.49: Installed. No version info available.
langchain-deepseek;: Installed. No version info available.
langchain-fireworks;: Installed. No version info available.
langchain-google-genai;: Installed. No version info available.
langchain-google-vertexai;: Installed. No version info available.
langchain-groq;: Installed. No version info available.
langchain-huggingface;: Installed. No version info available.
langchain-mistralai;: Installed. No version info available.
langchain-ollama;: Installed. No version info available.
langchain-openai;: Installed. No version info available.
langchain-text-splitters<1.0.0,>=0.3.7: Installed. No version info available.
langchain-together;: Installed. No version info available.
langchain-xai;: Installed. No version info available.
langchain<1.0.0,>=0.3.21: Installed. No version info available.
langsmith-pyo3: Installed. No version info available.
langsmith<0.4,>=0.1.125: Installed. No version info available.
langsmith<0.4,>=0.1.17: Installed. No version info available.
numpy: 1.26.4
numpy<3,>=1.26.2: Installed. No version info available.
openai-agents: Installed. No version info available.
opentelemetry-api: 1.31.1
opentelemetry-exporter-otlp-proto-http: Installed. No version info available.
opentelemetry-sdk: 1.31.1
orjson: 3.10.16
packaging: 24.2
packaging<25,>=23.2: Installed. No version info available.
pgvector: 0.3.6
psycopg: 3.2.6
psycopg-pool: 3.2.6
pydantic: 2.11.1
pydantic-settings<3.0.0,>=2.4.0: Installed. No version info available.
pydantic<3.0.0,>=2.5.2;: Installed. No version info available.
pydantic<3.0.0,>=2.7.4: Installed. No version info available.
pydantic<3.0.0,>=2.7.4;: Installed. No version info available.
pytest: 8.3.5
PyYAML>=5.3: Installed. No version info available.
requests: 2.32.3
requests-toolbelt: 1.0.0
requests<3,>=2: Installed. No version info available.
rich: 13.9.4
sqlalchemy: 2.0.40
SQLAlchemy<3,>=1.4: Installed. No version info available.
tenacity!=8.4.0,<10,>=8.1.0: Installed. No version info available.
tenacity!=8.4.0,<10.0.0,>=8.1.0: Installed. No version info available.
typing-extensions>=4.7: Installed. No version info available.
zstandard: 0.23.0

Originally created by @arindam-b on GitHub (Apr 4, 2025). Originally assigned to: @eyurtsev on GitHub. ### Checked other resources - [x] This is a bug, not a usage question. For questions, please use GitHub Discussions. - [x] I added a clear and detailed title that summarizes the issue. - [x] I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example). - [x] I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue. ### Example Code ```python from langgraph.types import interrupt def human_node(state: State): """Human node with validation.""" question = "What is your age?" while True: answer = interrupt(question) # Validate answer, if the answer isn't valid ask for input again. if not isinstance(answer, int) or answer < 0: question = f"'{answer} is not a valid age. What is your age?" answer = None continue else: # If the answer is valid, we can proceed. break print(f"The human in the loop is {answer} years old.") return { "age": answer } ``` ### Error Message and Stack Trace (if applicable) ```shell ``` ### Description The above example is taken from the url: https://langchain-ai.github.io/langgraph/concepts/human_in_the_loop/#validating-human-input The while loop breaks if the condition is not met. So the loop continues till the user is satisfied with the response. However, when the first **human_node** is called, it runs smoothly. But it is called second time, this blocks called twice. So, as many times as the question is asked, every time that is called that many times. For example, if the loop condition is satisfied to continue, the first time the logic will execute just once. But the second time, it will be executed precisely twice and third time, thrice. This can be overcome by another human_node for example, human_node_2 which checks the response and redirects the flow using a goto command, something like the following: ```python return Command( goto="check_continue_human_node", # The next node(s) to go to update={"ai_responses": [response]} # The update to apply to the state ) ``` ### System Info System Information ------------------ > OS: Linux > OS Version: #1 SMP PREEMPT_DYNAMIC Thu Jun 27 21:05:47 UTC 2024 > Python Version: 3.11.11 (main, Dec 4 2024, 08:55:07) [GCC 11.4.0] Package Information ------------------- > langchain_core: 0.3.50 > langchain: 0.3.22 > langchain_community: 0.3.20 > langsmith: 0.3.22 > langchain_aws: 0.2.18 > langchain_postgres: 0.0.13 > langchain_text_splitters: 0.3.7 > langgraph_sdk: 0.1.61 Optional packages not installed ------------------------------- > langserve Other Dependencies ------------------ > aiohttp<4.0.0,>=3.8.3: Installed. No version info available. > async-timeout<5.0.0,>=4.0.0;: Installed. No version info available. > boto3: 1.37.27 > dataclasses-json<0.7,>=0.5.7: Installed. No version info available. > httpx: 0.28.1 > httpx-sse<1.0.0,>=0.4.0: Installed. No version info available. > jsonpatch<2.0,>=1.33: Installed. No version info available. > langchain-anthropic;: Installed. No version info available. > langchain-aws;: Installed. No version info available. > langchain-azure-ai;: Installed. No version info available. > langchain-cohere;: Installed. No version info available. > langchain-community;: Installed. No version info available. > langchain-core<1.0.0,>=0.3.45: Installed. No version info available. > langchain-core<1.0.0,>=0.3.49: Installed. No version info available. > langchain-deepseek;: Installed. No version info available. > langchain-fireworks;: Installed. No version info available. > langchain-google-genai;: Installed. No version info available. > langchain-google-vertexai;: Installed. No version info available. > langchain-groq;: Installed. No version info available. > langchain-huggingface;: Installed. No version info available. > langchain-mistralai;: Installed. No version info available. > langchain-ollama;: Installed. No version info available. > langchain-openai;: Installed. No version info available. > langchain-text-splitters<1.0.0,>=0.3.7: Installed. No version info available. > langchain-together;: Installed. No version info available. > langchain-xai;: Installed. No version info available. > langchain<1.0.0,>=0.3.21: Installed. No version info available. > langsmith-pyo3: Installed. No version info available. > langsmith<0.4,>=0.1.125: Installed. No version info available. > langsmith<0.4,>=0.1.17: Installed. No version info available. > numpy: 1.26.4 > numpy<3,>=1.26.2: Installed. No version info available. > openai-agents: Installed. No version info available. > opentelemetry-api: 1.31.1 > opentelemetry-exporter-otlp-proto-http: Installed. No version info available. > opentelemetry-sdk: 1.31.1 > orjson: 3.10.16 > packaging: 24.2 > packaging<25,>=23.2: Installed. No version info available. > pgvector: 0.3.6 > psycopg: 3.2.6 > psycopg-pool: 3.2.6 > pydantic: 2.11.1 > pydantic-settings<3.0.0,>=2.4.0: Installed. No version info available. > pydantic<3.0.0,>=2.5.2;: Installed. No version info available. > pydantic<3.0.0,>=2.7.4: Installed. No version info available. > pydantic<3.0.0,>=2.7.4;: Installed. No version info available. > pytest: 8.3.5 > PyYAML>=5.3: Installed. No version info available. > requests: 2.32.3 > requests-toolbelt: 1.0.0 > requests<3,>=2: Installed. No version info available. > rich: 13.9.4 > sqlalchemy: 2.0.40 > SQLAlchemy<3,>=1.4: Installed. No version info available. > tenacity!=8.4.0,<10,>=8.1.0: Installed. No version info available. > tenacity!=8.4.0,<10.0.0,>=8.1.0: Installed. No version info available. > typing-extensions>=4.7: Installed. No version info available. > zstandard: 0.23.0
yindo closed this issue 2026-02-20 17:40:42 -05:00
Author
Owner

@eyurtsev commented on GitHub (Apr 4, 2025):

Could you paraphrase the issue? Is this a question about behavior or are you observing a bug?

LangGraph implements Durable Execution: https://langchain-ai.github.io/langgraph/concepts/durable_execution/

Perhaps place a print inside the while loop, and share what you see vs. what you expect to see.

@eyurtsev commented on GitHub (Apr 4, 2025): Could you paraphrase the issue? Is this a question about behavior or are you observing a bug? LangGraph implements Durable Execution: https://langchain-ai.github.io/langgraph/concepts/durable_execution/ Perhaps place a print inside the while loop, and share what you see vs. what you expect to see.
Author
Owner

@arindam-b commented on GitHub (Apr 4, 2025):

For my chatbot, it enters into a stage where it searches for information based on user inputs. If the user is done with the Q&A, it moves to the subsequent step. So unless it is done with the Q&A, it stays within the loop "while True".
When the user asks the question for the first time, it works perfectly. When he asks another question next time, it executes the user's query twice. For the 3rd question, it executes the 3rd time.
Of course I have used the print state to verify the execution.

from langgraph.types import interrupt


def human_node(state: InformationState):

  """Human node with validation."""

  question = "do you have more question? if no, just say No."

  while True:
        answer = interrupt(question)

        if answer.lower() == "no":
            print("got no")
            break
        else:
            ask_kb(answer, state.get("client_name")
            print("answer done")
            answer = None
            continue

So during the 2nd question, it prints "answer done" and also prints the lines within the execution of ask_kb twice.

And, of course, durable execution is an integral part of the system.

@arindam-b commented on GitHub (Apr 4, 2025): For my chatbot, it enters into a stage where it searches for information based on user inputs. If the user is done with the Q&A, it moves to the subsequent step. So unless it is done with the Q&A, it stays within the loop "while True". When the user asks the question for the first time, it works perfectly. When he asks another question next time, it executes the user's query twice. For the 3rd question, it executes the 3rd time. Of course I have used the print state to verify the execution. ```python from langgraph.types import interrupt def human_node(state: InformationState): """Human node with validation.""" question = "do you have more question? if no, just say No." while True: answer = interrupt(question) if answer.lower() == "no": print("got no") break else: ask_kb(answer, state.get("client_name") print("answer done") answer = None continue ``` So during the 2nd question, it prints "answer done" and also prints the lines within the execution of ask_kb twice. And, of course, durable execution is an integral part of the system.
Author
Owner

@eyurtsev commented on GitHub (Apr 4, 2025):

@arindam-b sorry still haven't a hard time following whether you have a question or what you expect to see vs. what you see.

from langgraph.types import interrupt


def human_node(state: InformationState):

  """Human node with validation."""
 idx = 0

  while True:
        idx += 1
        print(idx)
        answer = interrupt('something')
        if answer.lower() == "no":
            break

If the user input is:

yes, yes, yes, no

the expected output is:

1
1
2
1
2
3
1
2
3
4

If it's not clear why this is the correct output, please read over the durable execution conceptual guide to understand how resuming works after an interrupt

@eyurtsev commented on GitHub (Apr 4, 2025): @arindam-b sorry still haven't a hard time following whether you have a question or what you expect to see vs. what you see. ```python from langgraph.types import interrupt def human_node(state: InformationState): """Human node with validation.""" idx = 0 while True: idx += 1 print(idx) answer = interrupt('something') if answer.lower() == "no": break ``` If the user input is: yes, yes, yes, no the **expected** output is: 1 1 2 1 2 3 1 2 3 4 If it's not clear why this is the correct output, please read over the durable execution conceptual guide to understand how resuming works after an interrupt * https://langchain-ai.github.io/langgraph/concepts/durable_execution/#starting-points-for-resuming-workflows *
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#556