bytedance/deer-flow

[Stability][BUG-001] Gateway uses stale AppConfig after config.yaml changes

Closed

#3112 opened on May 21, 2026

View on GitHub
 (0 comments) (0 reactions) (0 assignees)Python (67,767 stars) (9,005 forks)batch import
help wanted

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.config still 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.

Contributor guide