666ghj/MiroFish · error · TimeoutError
等待命令响应超时 ({timeout}秒)
Error message
等待命令响应超时 ({timeout}秒) What it means
Raised by SimulationIPCClient.send_command: file-based IPC writes a command JSON into the commands dir, then polls every poll_interval (0.5s default) for a response file {command_id}.json in the responses dir. If no valid response appears within timeout (default 60s), it removes the command file and raises TimeoutError. This means the OASIS simulation subprocess is not consuming commands or is too slow to answer.
Source
Thrown at backend/app/services/simulation_ipc.py:187
pass
logger.info(f"收到IPC响应: command_id={command_id}, status={response.status.value}")
return response
except (json.JSONDecodeError, KeyError) as e:
logger.warning(f"解析响应失败: {e}")
time.sleep(poll_interval)
# 超时
logger.error(f"等待IPC响应超时: command_id={command_id}")
# 清理命令文件
try:
os.remove(command_file)
except OSError:
pass
raise TimeoutError(f"等待命令响应超时 ({timeout}秒)")
def send_interview(
self,
agent_id: int,
prompt: str,
platform: str = None,
timeout: float = 60.0
) -> IPCResponse:
"""
发送单个Agent采访命令
Args:
agent_id: Agent ID
prompt: 采访问题
platform: 指定平台(可选)
- "twitter": 只采访Twitter平台
- "reddit": 只采访Reddit平台
- None: 双平台模拟时同时采访两个平台,单平台模拟时采访该平台View on GitHub (pinned to b5b53acc57)
Solutions
- Check that the OASIS simulation subprocess is alive and its logs show it consuming the command file; restart it if crashed.
- Verify both processes agree on the commands/responses directories (absolute paths, same volume in Docker).
- Increase the timeout argument for slow operations like interviews (send_interview supports timeout=60 default).
- If logs show '解析响应失败', the response file is malformed — ensure the subprocess writes atomically (temp file + rename) and matches IPCResponse.from_dict's expected keys.
Example fix
# before resp = ipc.send_command(CommandType.INTERVIEW, args, timeout=60) # after resp = ipc.send_command(CommandType.INTERVIEW, args, timeout=180) # plus: subprocess should write responses atomically # tmp = response_file + '.tmp'; write; os.replace(tmp, response_file)
Defensive patterns
Strategy: retry
Validate before calling
def subprocess_alive(pid_file: str) -> bool:
try:
pid = int(open(pid_file).read().strip())
os.kill(pid, 0)
return True
except (OSError, ValueError):
return False Try / catch
try:
resp = ipc.send_command(cmd, args, timeout=180)
except TimeoutError:
if not subprocess_alive():
restart_simulation_subprocess()
resp = ipc.send_command(cmd, args, timeout=180) # one bounded retry Prevention
- Health-check the simulation subprocess before sending commands; restart on death.
- Write IPC files atomically (temp + os.replace) so half-written responses aren't read.
- Scale the timeout to the command type (interviews are slow; use send_interview's timeout).
When it happens
Trigger: Simulation process not started, crashed, or not watching the commands directory; response written after the deadline; response file present but unparseable (json.JSONDecodeError/KeyError in IPCResponse.from_dict is logged and skipped, so a malformed response also manifests as a timeout); commands/responses dirs pointing at different paths than the subprocess uses.
Common situations: Subprocess died earlier (check its logs) while the backend still sends interview/round commands; Docker volume mismatch so the two processes see different dirs; a long-running interview exceeding the 60s default timeout; concurrent runs sharing a directory with stale files; partially written response file read mid-write.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- 模拟仍在停止中,图谱写入未在 {wait_timeout:.0f}s 内完成
- 模拟环境未运行或已关闭,无法执行Interview: {simulation_id}
- GitHub GraphQL request timed out
- Zep batch {submission.batch_id} did not finish within {timeo
- Zep episode processing timed out with {len(pending_episodes)
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/2aeebe8311aad547.
Report an issue: GitHub.