When a zip/image arrives via /upload, the LLM was classifying the
message as needs_clarification=True (because the chat body was just a
filename like "download (8).zip", not an instruction), and the early
return on line 91 fired before the receipts safety guard on line 106,
so the guard never executed.
master_agent: move the receipts safety guard to BEFORE the
needs_clarification early-return. If extra_context contains receipts,
unconditionally set needs_clarification=False and ensure expenses_agent
is in the agents list — the LLM cannot veto an upload with a question.
upload router: normalize empty or filename-only messages (e.g. when the
user drops a file in Discuss chat with no text) to
"Create an expense report from these uploaded receipts." so the LLM
intent classification also has a sensible string to work with.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>