jsonToOpenUI drops parentheses on right operand of equal precedence ($a - ($b - $c) becomes $a - $b - $c)

Open
#1,463 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@ShryukGrandhi is already working on this.

Since Oct 23, 2026.

  • #1464 by @ShryukGrandhi — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
35/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
typescript

Research direction

The issue points to jsonToOpenUI in @openuidev/lang-core and says serializeBinOpChild receives an unused side argument. Read that serializer and its existing tests, then add a regression case for a same-precedence right operand such as $a - ($b - $c). Done means serialization preserves the parentheses; pull request 1464 is already open against this issue.

Written by the indexing model from the issue text.

Description

Describe the bug
jsonToOpenUI (in @openuidev/lang-core) drops the parentheses around a right-hand operand that has the same precedence as its parent operator. The parser is left-associative, so the serialized text means something different from the original expression. $a - ($b - $c) is written out as $a - $b - $c, which parses back as ($a - $b) - $c. The same thing happens with / and % (for example, $a / ($b * $c) becomes $a / $b * $c).

To Reproduce

import { jsonToOpenUI } from "@openuidev/lang-core";

const node = {
  type: "element",
  typeName: "Title",
  props: {
    text: {
      k: "BinOp",
      op: "-",
      left: { k: "StateRef", n: "$a" },
      right: {
        k: "BinOp",
        op: "-",
        left: { k: "StateRef", n: "$b" },
        right: { k: "StateRef", n: "$c" },
      },
    },
  },
  partial: false,
  hasDynamicProps: true,
};

jsonToOpenUI(node, library);
// => 'root = Title($a - $b - $c)'

With $a = 10, $b = 4, $c = 1, the original expression evaluates to 7. The serialized one evaluates to 5.

Expected behavior
root = Title($a - ($b - $c)). The right operand should keep its parentheses whenever its precedence is less than or equal to the parent's.

Actual behavior
root = Title($a - $b - $c). The parentheses are only kept when the child's precedence is strictly lower. serializeBinOpChild already receives a side argument but never uses it.

Environment

  • Package: @openuidev/lang-core (main @ 334faff2)
  • Node 24, macOS arm64

Additional context
I have a small fix with a regression test ready if that helps.

Dominant language
TypeScript
Stars
10k
Forks
698
Avg merge
1d 3h
Merged PRs (30d)
133

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

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.

More from thesysdev/openui

All issues in thesysdev/openui

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.