iflytek/astron-agent · error · Exception
Session closed and retry failed
Error message
Session closed and retry failed: {error} What it means
When an aiohttp session has been closed underneath an in-flight request, _make_request retries via _handle_session_error, which clears the cached global session. If the failure still occurs on the last allowed retry (attempt == max_retries - 1), it raises Exception('Session closed and retry failed: {error}'), signaling that session recycling did not recover the connection.
Solutions
- Call cleanup_session() (or recreate the session) after loop/session lifecycle events and re-issue the request
- Reduce session reuse issues by checking session.closed before reuse and proactively recreating
- Investigate why the underlying error repeated across retries (server availability, proxy timeouts)
- If keepalive is the cause, tune server/aiohttp keepalive timeouts so idle sessions are refreshed before the server drops them
Example fix
# before
await ragflow_retrieve(dataset_id, query)
# after
try:
await ragflow_retrieve(dataset_id, query)
except Exception as e:
if 'Session closed' in str(e):
await cleanup_session()
result = await ragflow_retrieve(dataset_id, query) Defensive patterns
Strategy: retry
Validate before calling
import aiohttp
from core.knowledge.infra.ragflow import ragflow_client as rc
async def session_usable() -> bool:
s = rc._session_cache
return s is not None and not s.closed Try / catch
try:
result = await ragflow_call(...)
except Exception as e:
if 'Session closed and retry failed' in str(e):
await cleanup_session()
result = await ragflow_call(...) # fresh session Prevention
- Call cleanup_session() on shutdown and after event-loop recreation
- Avoid sharing the module-level session across different event loops (e.g. tests)
- Keep RAGFlow server keepalive settings compatible with client session reuse
When it happens
Trigger: Calling any _make_request-backed RAGFlow operation while the cached aiohttp ClientSession is closed (e.g. after event-loop shutdown/restart, keepalive timeout on the server, or session garbage collection), and retries are exhausted.
Common situations: Long-lived service whose cached session outlived server keepalive; tests closing the loop/session between cases; deploying code that recreates the event loop while the module-level _session_cache persists; RAGFlow server restarting and dropping keepalive connections.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/f4f89c5a5bd3d649.
Report an issue: GitHub.
Appendix: source
Thrown at core/knowledge/infra/ragflow/ragflow_client.py:302
attempt: int, max_retries: int, error: Exception
) -> None:
"""
Handle session closed errors with retry logic
Args:
attempt: Current attempt number
max_retries: Maximum retry attempts
error: The error that occurred
Raises:
Exception: If max retries exceeded
"""
global _session_cache
_session_cache = None
logger.warning(f"Session closed, retrying... (attempt {attempt + 1}/{max_retries})")
if attempt == max_retries - 1:
raise Exception(f"Session closed and retry failed: {error}")
return None # This should never be reached but satisfies mypy
async def _make_request(
method: str,
endpoint: str,
data: Optional[Dict[str, Any]] = None,
files: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
"""
Common function for sending HTTP requests
Args:
method: HTTP method
endpoint: API endpoint
data: Request data
files: File data
View on GitHub (pinned to 5e758547a8)