{"record":{"id":"6482cc1de3710501","repo":"bytedance/deer-flow","slug":"failed-to-read-user-profile-str-e","errorCode":null,"errorMessage":"Failed to read user profile: {str(e)}","messagePattern":"Failed to read user profile: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"backend/app/gateway/routers/agents.py","lineNumber":501,"sourceCode":"    description=\"Read the global USER.md file that is injected into all custom agents.\",\n)\nasync def get_user_profile() -> UserProfileResponse:\n    \"\"\"Return the current USER.md content.\n\n    Returns:\n        UserProfileResponse with content=None if USER.md does not exist yet.\n    \"\"\"\n    _require_agents_api_enabled()\n\n    try:\n        user_md_path = get_paths().user_md_file\n        if not user_md_path.exists():\n            return UserProfileResponse(content=None)\n        raw = user_md_path.read_text(encoding=\"utf-8\").strip()\n        return UserProfileResponse(content=raw or None)\n    except Exception as e:\n        logger.error(f\"Failed to read user profile: {e}\", exc_info=True)\n        raise HTTPException(status_code=500, detail=f\"Failed to read user profile: {str(e)}\")\n\n\n@router.put(\n    \"/user-profile\",\n    response_model=UserProfileResponse,\n    summary=\"Update User Profile\",\n    description=\"Write the global USER.md file that is injected into all custom agents.\",\n)\nasync def update_user_profile(request: UserProfileUpdateRequest) -> UserProfileResponse:\n    \"\"\"Create or overwrite the global USER.md.\n\n    Args:\n        request: The update request with the new USER.md content.\n\n    Returns:\n        UserProfileResponse with the saved content.\n    \"\"\"\n    _require_agents_api_enabled()","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/agents.py#L483-L519","documentation":"Catch-all 500 on GET `/user-profile`: reading `paths.user_md_file` failed unexpectedly. A missing USER.md is normal and returns `content: null` (the `.exists()` check handles that), so this 500 means an actual IO error — permission denied, an unreadable file (I/O error, encoding failure on invalid UTF-8), or the path being a directory.","triggerScenarios":"USER.md owned by another user with no read permission; a USER.md written in a non-UTF-8 encoding causing decode failure; the profile path replaced by a directory via a bad mount.","commonSituations":"Volume permission drift in containers; operators writing USER.md with a tool that saved latin-1; symlink loops.","solutions":["Check `get_paths().user_md_file` on disk: permissions, encoding, that it is a regular file","Rewrite the file as UTF-8 or delete it (absence is a supported state returning null)","Fix mount/ownership on the base_dir volume"],"exampleFix":"# before: file saved as latin-1 -> UnicodeDecodeError -> 500\n# after\niconv -f latin-1 -t utf-8 USER.md -o USER.md.utf8 && mv USER.md.utf8 USER.md","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await api.getUserProfile(); }\ncatch (e) {\n  if (e.status === 500 && /read user profile/.test(e.detail)) {\n    return { content: null, degraded: true }; // missing profile is a valid empty state anyway\n  }\n  throw e;\n}","preventionTips":["Ensure USER.md is always written as UTF-8","Check file permissions on the profile path during deployment smoke tests","A 500 here means the file exists but is unreadable — inspect encoding/permissions, not existence"],"tags":["http-500","user-profile","filesystem","encoding"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}