Problem Description
I'm building a backend using LangServe and FastAPI. My API endpoint encounters a 422 error when using RunnablePassthrough() or RunnableParallel, but works when I add RunnableLambda at the beginning. All versions work
perfectly in local testing.
Detailed Issue
Chains that fail in LangServe (422 error):
#python
# Failing Option 1 - RunnablePassthrough
chain = (
RunnablePassthrough()
.assign(
context=lambda x: retriever.invoke(x["question"]),
question=lambda x: x["question"]
)
| prompt
| llm
| StrOutputParser()
)
# Failing Option 2 - RunnableParallel
chain = (
RunnableParallel({
"context": lambda x: retriever.invoke(x["question"]),
"question": lambda x: x["question"]
})
| prompt
| llm
| StrOutputParser()
)
Working solution with RunnableLambda:
#python
def debug_input(x):
print(f"[QA Chain] Actual input received: {x}, type: {type(x)}")
return x
chain = (
RunnableLambda(debug_input)
.assign(
context=lambda x: retriever.invoke(x["question"]),
question=lambda x: x["question"]
)
| prompt
| llm
| StrOutputParser()
)
Important Additional Information
Local testing works fine:
When I test the same chain locally in the API's main Python file, all versions work correctly:
#python
if __name__ == "__main__":
# Test pipeline
qa_chain = load_qa_chain()
test_question = "What are the core functions of the void system?"
result = qa_chain.invoke({"question": test_question})
print(f"Q: {test_question}\nA: {result}")
Key Observations
All versions work perfectly in local testing
The issue only occurs when exposing the chain through LangServe/FastAPI
(I'm using standard LangServe registration without any custom unpacking logic)
After examining the source code, I found that RunnableLambda has more flexible input acceptance
Both RunnablePassthrough and RunnableParallel also accept Any input but appear to have stricter validation in the LangServe environment
Questions I'd Like to Understand
Why do RunnablePassthrough and RunnableParallel fail with 422 errors in LangServe while working perfectly in local testing?
Why does adding RunnableLambda resolve this issue?
Is there a fundamental difference in how these components handle input validation in LangServe vs local execution?
What would be the proper way to use RunnablePassthrough and RunnableParallel in LangServe without the workaround?
Additional Context
I'm a university student working on this project and encountered this issue over the past couple of days. I've tried analyzing the source code with AI assistance but still can't figure out the root cause. If this turns out to be a simple or obvious issue, I apologize in advance and would appreciate your guidance.
Thank you for any insights into this behavior!
Problem Description
I'm building a backend using LangServe and FastAPI. My API endpoint encounters a 422 error when using RunnablePassthrough() or RunnableParallel, but works when I add RunnableLambda at the beginning. All versions work
perfectly in local testing.
Detailed Issue
Chains that fail in LangServe (422 error):
Working solution with RunnableLambda:
Important Additional Information
Local testing works fine:
When I test the same chain locally in the API's main Python file, all versions work correctly:
Key Observations
All versions work perfectly in local testing
The issue only occurs when exposing the chain through LangServe/FastAPI
(I'm using standard LangServe registration without any custom unpacking logic)
After examining the source code, I found that RunnableLambda has more flexible input acceptance
Both RunnablePassthrough and RunnableParallel also accept Any input but appear to have stricter validation in the LangServe environment
Questions I'd Like to Understand
Why do RunnablePassthrough and RunnableParallel fail with 422 errors in LangServe while working perfectly in local testing?
Why does adding RunnableLambda resolve this issue?
Is there a fundamental difference in how these components handle input validation in LangServe vs local execution?
What would be the proper way to use RunnablePassthrough and RunnableParallel in LangServe without the workaround?
Additional Context
I'm a university student working on this project and encountered this issue over the past couple of days. I've tried analyzing the source code with AI assistance but still can't figure out the root cause. If this turns out to be a simple or obvious issue, I apologize in advance and would appreciate your guidance.
Thank you for any insights into this behavior!