makeplane / makeplane/plane-python-sdk
[bug]: update() strips None values via exclude_none=True, making it impossible to clear nullable fields
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 17
- Forks
- 24
- Merge moyen
- 8 j 9 h
- PR mergées (30 j)
- 2
Description
Summary
The update() method on every resource class strips None values from the payload via model_dump(exclude_none=True),
making it impossible to clear any nullable field on an existing work item (or any other resource using the same
pattern).
Reproducer
# Setup: work item with target_date = "2026-05-17"
data = UpdateWorkItem(target_date=None)
client.work_items.update(
workspace_slug=ws, project_id=p, work_item_id=w, data=data,
)
# Expected: target_date cleared to null
# Actual: silent no-op — target_date still 2026-05-17
# Wire body sent: {} (None stripped by exclude_none=True)
Root cause
plane/api/work_items/base.py line 102 (same pattern in other resources):
response = self._patch(
f"{workspace_slug}/projects/{project_id}/work-items/{work_item_id}",
data.model_dump(exclude_none=True),
)
exclude_none=True conflates two distinct user intents: "do not update this field" and "clear this field to null."
Impact
Affects every nullable field on every resource using this pattern: target_date, start_date, parent, point,
description_html, assignees (back to empty), etc. Currently the only workaround is clearing in the Plane web UI.
Proposed fix (two viable shapes)
A. Switch to exclude_unset=True + explicit None for clears
- Caller passes
Noneto mean "clear," and omits the field entirely to mean "don't change." - Requires the data model to distinguish unset from None (Pydantic v2 supports this natively).
- Breaking change for callers that currently pass
Noneexpecting "don't change."
B. Add explicit clear: list[str] parameter to update() methods
- Caller passes e.g.
clear=["target_date", "parent"]and the wrapper injectsnullfor those fields after
model_dump. - Non-breaking; opt-in.
- More verbose but unambiguous.
Happy to send a PR with whichever shape the maintainers prefer.
Environment
plane-sdk0.2.10 (also present onmainHEAD as of 2026-05-17)- Plane Cloud workspace
- Discovered via
plane-mcp-server'supdate_work_itemtool, but the bug is in the SDK, not the MCP wrapper.
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez dans plane/api/work_items/base.py vers la ligne 102, puis recherchez le même modèle model_dump(exclude_none=True) dans les autres classes de ressources. Comparez la manière dont les champs non définis et None explicite sont représentés dans les modèles de mise à jour avant de choisir entre les deux approches proposées. Le travail est terminé lorsque les champs nullable peuvent être vidés sans transformer les champs omis en mises à jour dans les ressources concernées.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- api, backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100