makeplane / makeplane/plane

[bug]: plane push cannot sync OPTION custom property values

Open
#9,558 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
59.6k
Forks
5.8k
Avg merge
1d 22h
Merged PRs (30d)
49

Description

  • I have searched the existing issues

Current behavior

When a project has an OPTION (single or multi-select) custom property attached to a
work item type, plane push fails for every work item that carries a value for it.

What I expect is that option names are resolved to option IDs (the same name-based
matching compose already does for labels and assignees) and the values sync.

Error 1 — names sent to the API

Using option names in work/workitems.yaml:

properties:
  Flag: [alpha]

plane push fails with:

ERROR API error 400: value: Invalid UUID format: alpha
Error 2 — UUIDs rejected by the validator

Using the option's UUID instead of its name:

properties:
  Flag: [<option-uuid>]

plane push now aborts at its own validation gate:

Unknown option(s) for property 'Flag': <option-uuid>

Net result: neither option names nor option UUIDs can be pushed — OPTION property
values are unsynceable.

Related: replace_existing deletes undeclared property values

On item update, _set_work_item_properties(..., replace_existing=True) deletes
property values not present in the YAML. For a property whose value was never set,
the DELETE returns 404 Property value not set for this work item; only
NotFoundError is caught in _delete_property_value, but the SDK surfaces this as a
generic APIError, so the exception escapes and the whole item update fails:

ERROR API error 404: Property value not set for this work item

This also means any item whose type has a custom property attached fails to push
even when no properties are declared in the YAML at all.

Steps to reproduce

  1. Define a work item type with an OPTION property (is_multi: true, options
    alpha, beta) in schema/types.yaml and push the schema:

    plane push
    
  2. In work/workitems.yaml, set the property value on an item using option names:

    properties:
      Flag: [alpha]
    
  3. Validate:

    plane validate
    

    passes (option names match the local schema).

  4. Push:

    plane push
    

    fails with the 400 error above.

  5. Workaround attempt — use the option's UUID instead of its name:

    properties:
      Flag: [<option-uuid>]
    
  6. Push again:

    plane push
    

    now aborts at its own validation gate instead (error 2 above).

Root cause

In backend/plane.py, _set_option_property decides whether to resolve option
names to IDs with:

if "option" in prop_info["property_type"]:

but the Plane API returns the property type as OPTION (uppercase), so this branch
is never taken and raw values are sent to the API, which requires option UUIDs.
The validator, meanwhile, compares values against the option names declared in
the local schema, so the two stages can never agree.

Environment

  • Variant: Cloud
  • Version: plane-compose 0.5.2
  • Python 3.14
  • Browser: Not applicable (CLI tool)

Expected behaviour

  • Option names should be resolved to option IDs before the API call (the same
    name-based matching compose already does for labels and assignees).
  • replace_existing cleanup should tolerate missing property values (the 404 path
    is already handled for the "value already deleted" case — it just isn't
    classified as NotFoundError).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in backend/plane.py, inspecting _set_option_property, the property validator, and _delete_property_value. Reproduce with the schema/types.yaml and work/workitems.yaml examples, then run plane validate and plane push. Done means option names and IDs are accepted and resolving values works, while replace_existing does not fail when a property value is absent.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.