A profile has been created, and user wants to add skills (which is jsonb field) to the profile
19:24 11 Dec 2025

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: this the error message from my terminal

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
postgresql fastapi