{"record":{"id":"18e4fa39afd12a8d","repo":"bytedance/deer-flow","slug":"failed-to-update-agent-str-e","errorCode":null,"errorMessage":"Failed to update agent: {str(e)}","messagePattern":"Failed to update agent: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"backend/app/gateway/routers/agents.py","lineNumber":464,"sourceCode":"        # Persist config (when changed) and/or soul (when provided) off the\n        # event loop. A no-change PATCH commits nothing and re-reads current state.\n        if updated is not None or request.soul is not None:\n            await asyncio.to_thread(store.update, name, updated, request.soul, user_id=user_id)\n\n        logger.info(f\"Updated agent '{name}'\")\n\n        def _refresh() -> AgentResponse:\n            # Worker thread: re-read config + SOUL off the event loop.\n            refreshed_cfg = load_agent_config(name, user_id=user_id)\n            return _agent_config_to_response(refreshed_cfg, include_soul=True, user_id=user_id)\n\n        return await asyncio.to_thread(_refresh)\n\n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"Failed to update agent '{name}': {e}\", exc_info=True)\n        raise HTTPException(status_code=500, detail=f\"Failed to update agent: {str(e)}\")\n\n\nclass UserProfileResponse(BaseModel):\n    \"\"\"Response model for the global user profile (USER.md).\"\"\"\n\n    content: str | None = Field(default=None, description=\"USER.md content, or null if not yet created\")\n\n\nclass UserProfileUpdateRequest(BaseModel):\n    \"\"\"Request body for setting the global user profile.\"\"\"\n\n    content: str = Field(default=\"\", description=\"USER.md content — describes the user's background and preferences\")\n\n\n@router.get(\n    \"/user-profile\",\n    response_model=UserProfileResponse,\n    summary=\"Get User Profile\",","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/agents.py#L446-L482","documentation":"Catch-all 500 on PUT `/agents/{name}`: any exception during the update pipeline that is not itself an HTTPException — config write failures, SOUL.md write errors, serializer issues, or the post-update re-read failing. Genuine HTTPExceptions (404, 409 legacy, 422 model) are re-raised untouched, so this 500 always means an unexpected storage-layer failure.","triggerScenarios":"Permission denied rewriting config.yaml; disk full writing SOUL.md; concurrent writers corrupting the file between read and write; DB update constraint failure.","commonSituations":"Long-running servers whose data dir ownership changed; two tabs updating the same agent; partial writes after a crash leaving an unreadable config that then fails the refresh read.","solutions":["Read the logged traceback (`Failed to update agent '<name>'`) to find the failing step","Fix filesystem permissions/disk issues on the agents directory","If the config is now corrupt, restore from backup or recreate the agent","Serialize agent updates in the UI to avoid read-modify-write races"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await api.updateAgent(name, body); }\ncatch (e) {\n  if (e.status === 500 && /Failed to update agent/.test(e.detail)) {\n    const fresh = await api.getAgent(name); // verify post-failure state before retry\n    throw new AgentUpdateFailedError(name, e.detail, fresh);\n  }\n  throw e;\n}","preventionTips":["Because update is read-modify-write, re-read the agent after any failure before retrying","Serialize concurrent edits to the same agent in the UI","Watch for permission/disk errors in logs when 500s cluster on updates"],"tags":["http-500","agents","update","filesystem","persistence"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}