makeplane / makeplane/plane-python-sdk
[bug]: update() strips None values via exclude_none=True, making it impossible to clear nullable fields
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 17
- フォーク
- 24
- 平均マージ
- 8日 9時間
- マージ済み PR(30日)
- 2
説明
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.
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
plane/api/work_items/base.py の 102 行目付近から始め、他のリソースクラスで同じ model_dump(exclude_none=True) パターンを検索してください。2 つの提案されたアプローチのどちらかを選ぶ前に、更新モデルで未設定のフィールドと明示的な None がどのように表現されているかを比較してください。影響を受けるリソースで、省略されたフィールドを更新に変えることなく nullable フィールドをクリアできれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- api, backend
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 静か
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 45/100