bytedance/deer-flow · error · HTTPException

str(e)

Error message

str(e)

What it means

504 from POST /lark/config/start when start_lark_config raises TimeoutError. The begin step is a blocking urllib POST to https://accounts.feishu.cn (via _post_lark_form / _request_lark_app_registration_begin); a socket-level timeout surfaces here. detail=str(e) carries the underlying timeout text.

Source

Thrown at backend/app/gateway/routers/integrations.py:301

        logger.error("Failed to install Lark integration: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Failed to install Lark integration.")


@router.post("/lark/config/start", response_model=LarkConfigStartResponse, summary="Start Lark/Feishu App Configuration")
async def start_lark_app_config(body: LarkConfigStartRequest) -> LarkConfigStartResponse:
    try:
        result = await asyncio.to_thread(
            start_lark_config,
            get_effective_user_id(),
            brand=body.brand,
        )
        return _config_start_to_response(result)
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except TimeoutError as e:
        raise HTTPException(status_code=504, detail=str(e))
    except Exception as e:
        logger.error("Failed to start Lark connection setup: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Failed to start Lark connection setup.")


@router.post("/lark/config/complete", response_model=LarkConfigCompleteResponse, summary="Complete Lark/Feishu App Configuration")
async def complete_lark_app_config(request: Request, body: LarkConfigCompleteRequest, config: AppConfig = Depends(get_config)) -> LarkConfigCompleteResponse:
    try:
        result = await asyncio.to_thread(
            complete_lark_config,
            get_effective_user_id(),
            config,
            device_code=body.device_code,
            generation=body.generation,
            brand=body.brand,
            interval=body.interval,
            expires_in=body.expires_in,
        )

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. From the Gateway container, verify reachability: curl -m 10 https://accounts.feishu.cn
  2. Fix egress rules/DNS so the Gateway can reach *.feishu.cn (and *.larksuite.com for lark brand)
  3. Retry after network is fixed; no state was persisted by the failed start
  4. If behind a proxy, configure it for the Gateway process (HTTP_PROXY/HTTPS_PROXY)
Defensive patterns

Strategy: retry

Validate before calling

await api.post('/integrations/healthcheck', {}, { timeout: 3000 }); // or ping accounts.feishu.cn from ops tooling

Try / catch

try { ... } catch (e) {
  if (e?.response?.status === 504) { await delay(5000); retryOnce(); }
}

Prevention

When it happens

Trigger: The Gateway cannot reach accounts.feishu.cn within the urllib timeout: blocked egress, DNS failure resolved slowly, or an intermediate proxy stalling the connection. Also the file-lock path _replace/save timeouts are not in this endpoint, so network is the realistic cause.

Common situations: Gateway containers without outbound internet, DNS misconfiguration in Docker, firewall allowing only specific domains, Feishu accounts endpoint being slow during outages.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/0d6d4efc87c4919f. Report an issue: GitHub.