{"record":{"id":"4a60f37726952934","repo":"datawhalechina/hello-agents","slug":"error-4a60f3","errorCode":null,"errorMessage":"请先设置角色","messagePattern":"请先设置角色","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/megg-ops-roleplay_agent/roleplay_agent.py","lineNumber":80,"sourceCode":"        \n        # 初始化对话历史\n        self.chat = [\n            {\"role\": \"system\", \"content\": system_instruction},\n            {\"role\": \"assistant\", \"content\": self.character_config['opening_line']}\n        ]\n        \n        print(f\"\\n✅ 成功初始化角色: {self.character_config['name']} (来自 {self.character_config['source_material']})\")\n        print(f\"💡 {self.character_config['name']}: {self.character_config['opening_line']}\")\n        print(\"\\n\" + \"=\"*50)\n        print(\"开始对话吧！输入 'quit' 或 'exit' 退出，输入 'new' 开始新角色。\")\n        print(\"=\"*50)\n\n    def send_message(self, message):\n        \"\"\"\n        发送消息给 AI 并获取响应\n        \"\"\"\n        if not self.chat:\n            raise ValueError(\"请先设置角色\")\n        \n        # 添加用户消息到对话历史\n        self.chat.append({\"role\": \"user\", \"content\": message})\n        \n        try:\n            # 调用 API\n            response = self.client.chat.completions.create(\n                model=self.model_id,\n                messages=self.chat,\n                temperature=0.9,  # 增加创造性\n                max_tokens=1024\n            )\n            \n            # 获取响应内容\n            response_text = response.choices[0].message.content\n            # 添加到对话历史\n            self.chat.append({\"role\": \"assistant\", \"content\": response_text})\n            ","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/megg-ops-roleplay_agent/roleplay_agent.py#L62-L98","documentation":"CharacterRoleplayAgent.send_message() raises ValueError('请先设置角色') when self.chat is still falsy. The conversation list is only created during character setup (the method that prints '成功初始化角色'), so this error means the caller invoked send_message before any character was configured — the roleplay loop's internal state machine was skipped. It is a pure ordering/state error, not an API or network problem.","triggerScenarios":"Constructing CharacterRoleplayAgent() and immediately calling send_message('hi'); calling send_message after a 'new'/reset command cleared self.chat; an exception during character setup that left the agent half-initialized; automating the agent in a script that assumes a default character exists.","commonSituations":"Batch/script wrappers that skip the interactive character-selection prompt; a crash in setup_character swallowed by a broad except so the caller wrongly proceeds; REPL flow where the user types a message before choosing a character; tests that exercise send_message without the setup fixture.","solutions":["Call the character-setup flow first (the method that initializes self.character_config and self.chat — e.g. setup/opening printed with '✅ 成功初始化角色'), then send_message.","If setup already ran, check it did not raise partway: wrap it in try/except and abort the turn instead of continuing to send_message.","Add a ready check in your caller: if not getattr(agent, 'chat', None): agent.setup_character(...) before messaging.","Make setup idempotent and re-callable after 'new' so state can never be chat-less while the loop keeps accepting input."],"exampleFix":"# before\nagent = CharacterRoleplayAgent()\nreply = agent.send_message(\"hello\")\n# after\nagent = CharacterRoleplayAgent()\nagent.setup_character()  # or set_character(...) — initializes agent.chat\nreply = agent.send_message(\"hello\")","handlingStrategy":"validation","validationCode":"def ensure_ready(agent) -> None:\n    if not getattr(agent, \"chat\", None):\n        raise RuntimeError(\"character not set — call setup/set character before messaging\")\n\nensure_ready(agent)\nagent.send_message(\"hello\")","typeGuard":"from typing import Protocol\n\nclass ChatReady(Protocol):\n    chat: list\n\ndef is_chat_ready(agent) -> bool:\n    return bool(getattr(agent, \"chat\", None))","tryCatchPattern":"try:\n    agent.send_message(msg)\nexcept ValueError as e:\n    if \"请先设置角色\" in str(e):\n        agent.setup_character()  # recover once, then retry\n        reply = agent.send_message(msg)\n    else:\n        raise","preventionTips":["Make the interactive loop refuse input until a character is set","Reset self.chat atomically with the rest of state on 'new'","Guard library entry points with ready-checks instead of relying on internal attribute state"],"tags":["state-machine","initialization-order","python","validation"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}