[Stability][BUG-001] Gateway uses stale AppConfig after config.yaml changes
#3112 opened on May 21, 2026
Description
Parent stability dashboard: #3107
This issue tracks BUG-001 from #3107.
Problem
Changing config.yaml while the gateway process is running does not reliably affect subsequent runs. Model/runtime settings can remain stuck on the value captured at gateway startup until the gateway process is restarted.
This can create a split-brain runtime state:
- global
get_app_config()may reload the changed file; request.app.state.configstill points to the startup snapshot;- initialized runtime components still use the old config;
- fallback paths may see a different config than the main run path.
Code evidence
Startup loads config once:
# backend/app/gateway/app.py
app.state.config = get_app_config()
Per-request dependency returns the startup snapshot:
# backend/app/gateway/deps.py
def get_config(request: Request) -> AppConfig:
return getattr(request.app.state, "config", None)
The run context passes that snapshot forward:
# backend/app/gateway/deps.py
return RunContext(..., app_config=config)
The worker injects the same snapshot into the runtime and agent factory:
# backend/packages/harness/deerflow/runtime/runs/worker.py
runtime_ctx = _build_runtime_context(..., ctx.app_config)
agent = agent_factory(config=runnable_config, app_config=ctx.app_config)
The lead agent skips get_app_config() because runtime_app_config is already present:
# backend/packages/harness/deerflow/agents/lead_agent/agent.py
return _make_lead_agent(config, app_config=runtime_app_config or get_app_config())
Runtime component impact
langgraph_runtime(app) initializes these components from app.state.config at startup:
- stream bridge
- persistence engine
- checkpointer
- store
- run event store
- run manager
Those components are not rebuilt when config.yaml changes.
Observed behavior
Source: gateway log, token usage middleware.
LLM token usage: input=32433 output=8192 total=40625 ... finish_reason=length
LLM token usage: input=40653 output=8192 total=48845 ... finish_reason=length
LLM token usage: input=57478 output=8192 total=65670 ... finish_reason=length
After restarting the gateway process:
Source: gateway log, patched DeepSeek request payload debug.
[deepseek-payload-debug] model=deepseek-v4-pro self.max_tokens=384000 payload.max_tokens=384000
Source: gateway log, token usage middleware.
LLM token usage: input=29460 output=10579 total=40039
Expected behavior
Either config changes should be applied consistently across the request/run/runtime path, or hot reload should be explicitly unsupported for these fields with a clear restart-required boundary.