I have a user_profile model which is created right after a user signup, but here is the case a user wants to add skills to his profile after creation. The skills field is a jsonb data type, i dont want to change to a different data type because jsonb fits into my requirement.
I receive this error message when i try to send a request body:

here is my user_model:
class UserProfile(BaseModel):
__tablename__ = "user_profiles"
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), unique=True, nullable=False, index=True)
headline = Column(String(200))
summary = Column(Text)
location = Column(JSONB, default=dict)
professional_data = Column(JSONB, default=dict)
skills = Column(JSONB, default=list)
education_history = Column(JSONB, default=list)
work_experience = Column(JSONB, default=list)
video_profile_id = Column(UUID(as_uuid=True), ForeignKey("media_assets.id"), index=True)
visibility_settings = Column(String, default="public")
search_vector = Column(TSVECTOR, index=True)
profile_completeness = Column(SmallInteger, default=0)
# Relationships
user = relationship("User", back_populates="profile")
video_profile = relationship("MediaAsset", foreign_keys=[video_profile_id])
here is my add skill function:
async def add_skill(self, user_id: UUID, skill: Skill):
profile = await self.get_profile(user_id)
if not profile:
profile = UserProfile(user_id=user_id, skills=[])
self.db.add(profile)
await self.db.commit()
await self.db.refresh(profile)
# normalize
skill_name_lower = skill.name.lower()
# check duplicates
exists = any(s["name"].lower() == skill_name_lower for s in profile.skills)
if not exists:
profile.skills.append(skill.dict())
await self.db.commit()
await self.db.refresh(profile)
await self.update_search_vector(profile)
return profile.skills
my schema:
class Skill(BaseModel):
name: str
category: Optional[str] = None
proficiency: Optional[str] = None # Beginner, Intermediate, Advanced, Expert
class config:
from_attributes = True
my endpoint:
@router.post("/skills/add")
async def add_skill(data: Skill, current_user=Depends(get_current_user), db: AsyncSession = Depends(get_db)):
profile_service = ProfileService(db)
skills = await profile_service.add_skill(current_user.id, data)
return {"skills": skills}
finally my get user profile function:
async def get_profile(self, user_id: UUID) -> FullUserProfileResponse:
# return full profile, uses cache when available
cached = await self.get_cached_profile(user_id)
if cached:
return cached
profile = await self.get_profile_user_by_id(user_id)
if not profile:
raise ValueError("User not found")
profile_picture = await self.get_profile_picture(profile.user)
# Load related profile
payload = {
"id": str(profile.user_id), # or profile.id if needed
"email": profile.user.email if profile.user else None,
"username": profile.user.username if profile.user else None,
"full_name": profile.user.full_name if profile.user else None,
"avatar_url": await self.build_media_url(profile.user.avatar_url),
"profile_image": await self.build_media_url(profile_picture),
"video_profile_id": str(profile.video_profile_id) if profile.video_profile_id else None,
"profile": {
"headline": profile.headline,
"summary": profile.summary,
"location": profile.location,
"professional_data": profile.professional_data,
"skills": profile.skills or [],
"education_history": profile.education_history or [],
"work_experience": profile.work_experience or [],
"visibility_settings": profile.visibility_settings,
"profile_completeness": profile.profile_completeness or 0,
}
}
# cache result
await self.cache_profile_response(user_id, payload)
return payload