[bug]: update() strips None values via exclude_none=True, making it impossible to clear nullable fields

Aperta
#35 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
python
Ambito
api, backend

Direzione di ricerca

Inizia da plane/api/work_items/base.py intorno alla riga 102, quindi cerca lo stesso pattern model_dump(exclude_none=True) nelle altre classi di risorse. Confronta il modo in cui i campi non impostati e None esplicito sono rappresentati nei modelli di aggiornamento prima di scegliere tra i due approcci proposti. Il lavoro è completato quando i campi nullable possono essere svuotati senza trasformare i campi omessi in aggiornamenti nelle risorse interessate.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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 None to 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 None expecting "don't change."

B. Add explicit clear: list[str] parameter to update() methods

  • Caller passes e.g. clear=["target_date", "parent"] and the wrapper injects null for 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-sdk 0.2.10 (also present on main HEAD as of 2026-05-17)
  • Plane Cloud workspace
  • Discovered via plane-mcp-server's update_work_item tool, but the bug is in the SDK, not the MCP wrapper.
Lingua principale
Python
Stelle
17
Fork
24
Merge medio
8g 9h
PR unite (30g)
2

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di makeplane/plane-python-sdk

Tutte le issue di makeplane/plane-python-sdk

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.