Skip to content

fix(core): add @ignoreClone to Transform._parentTransformCache#3036

Merged
GuoLei1990 merged 3 commits into
dev/2.0from
fix/transform-reparent-propagation
Jun 20, 2026
Merged

fix(core): add @ignoreClone to Transform._parentTransformCache#3036
GuoLei1990 merged 3 commits into
dev/2.0from
fix/transform-reparent-propagation

Conversation

@cptbtptpbcptdtptp

@cptbtptpbcptdtptp cptbtptpbcptdtptp commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Transform._parentTransformCache 缺少 @ignoreClone,导致 clone 过程中 cloneProperty 覆盖了已被 listener resolve 过的 cache,产生 stale state(_isParentDirty=false, _parentTransformCache=null)。
  • 后续 reparent 时 _getParentTransform 直接返回 null → worldMatrix = localMatrix,不反映新 parent 的偏移。

Root cause

  1. _createCloneEntity 创建 clone 树时,Script 构造函数注册了 transform 变化 listener
  2. _parseCloneEntity clone Transform 属性时,某个属性赋值触发 dirty dispatch → listener 读 worldMatrix_getParentTransform resolve → _isParentDirty=false
  3. cloneProperty 继续遍历到 _parentTransformCache → 用源的值覆盖 → 写入 null
  4. 结果:_isParentDirty=false + _parentTransformCache=null → stale

Fix

_parentTransformCache@ignoreClone(一行)。clone 后保持默认值 null + _isParentDirty=true(也是 @ignoreClone),首次 _getParentTransform 调用会正确 resolve。

Test plan

  • pnpm run test — Transform tests pass (5/5)
  • 单测复现:clone 带 worldMatrix listener 的 entity,reparent 后 child worldMatrix 正确反映新 parent 偏移

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed incorrect transform results when cloning and reparenting entity hierarchies, ensuring cached transform data doesn’t cause stale world-matrix values. Cloned children now correctly reflect the new parent/root positioning.
  • Tests
    • Added coverage for scenarios where world-matrix values are accessed during cloning, validating both clone+reparent and subtree translation correctness.

…d UITransform

_parentChange() previously called _updateAllWorldFlag(), which has an
early-exit when the current node already has all target world dirty flags
set. After reparent, a descendant whose WorldMatrix flag was previously
cleared keeps returning stale cached worldMatrix.

Replace with _propagateReparentDirty / _propagateReparentDirtyUI that
unconditionally recurse through all descendants, setting _isParentDirty
and world dirty flags regardless of the current node's flag state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

@ignoreClone is added to the private _parentTransformCache field in Transform, excluding it from clone operations. Two new tests verify that after cloning a parent–child entity hierarchy and reparenting the clone under a positioned root, the clone child's worldMatrix translation correctly reflects the composed transform without stale cache, including edge cases where worldMatrix is accessed during the clone operation itself.

Changes

Fix stale parent-cache on clone

Layer / File(s) Summary
@ignoreClone on _parentTransformCache and reparent worldMatrix test
packages/core/src/Transform.ts, tests/src/core/Transform.test.ts
_parentTransformCache is marked with @ignoreClone to prevent cloned transforms from inheriting a stale parent reference. A WorldMatrixListener script test triggers worldMatrix access, clones a hierarchy, reparents the clone under a positioned root, and asserts the clone child's worldMatrix translation equals the composed root-plus-child-local position.
Validate worldMatrix correctness when read during _cloneTo
tests/src/core/Transform.test.ts
A WorldReaderOnClone script test reads worldMatrix inside _cloneTo during the clone operation, then reparents and validates that the cloned subtree's worldMatrix translation reflects the new root position rather than stale or local coordinates.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related issues

Poem

A cache clung tight through every clone,
But now it's told to stay at home.
The rabbit hops, the matrix clears,
No stale transform to cause us fears.
🐇 @ignoreClone — the world is right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the primary fix: adding the @ignoreClone decorator to Transform._parentTransformCache to resolve a critical cloning and reparenting bug.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/transform-reparent-propagation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.76%. Comparing base (97d8d61) to head (d597e88).
⚠️ Report is 6 commits behind head on dev/2.0.

Additional details and impacted files
@@             Coverage Diff             @@
##           dev/2.0    #3036      +/-   ##
===========================================
+ Coverage    77.31%   79.76%   +2.45%     
===========================================
  Files          914      914              
  Lines       101723   101797      +74     
  Branches     10437    11198     +761     
===========================================
+ Hits         78647    81203    +2556     
+ Misses       22892    20413    -2479     
+ Partials       184      181       -3     
Flag Coverage Δ
unittests 79.76% <100.00%> (+2.45%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

GuoLei1990

This comment was marked as outdated.

GuoLei1990

This comment was marked as outdated.

During clone, ComponentCloner.cloneProperty overwrites
_parentTransformCache after a listener has already resolved it,
producing a stale state (_isParentDirty=false, cache=null). On
subsequent reparent, _getParentTransform returns null from cache
and worldMatrix falls back to localMatrix.

Root cause: _parentTransformCache lacked @ignoreClone, so cloneProperty
copied the source's value over the already-resolved cache. With
@ignoreClone, clone keeps the default null + _isParentDirty=true
(also @ignoreClone), so the first _getParentTransform call after
clone resolves correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cptbtptpbcptdtptp cptbtptpbcptdtptp force-pushed the fix/transform-reparent-propagation branch from ac3a325 to 147d178 Compare June 15, 2026 12:16
@cptbtptpbcptdtptp cptbtptpbcptdtptp changed the title fix(core/ui): propagate reparent dirty to descendants in Transform and UITransform fix(core): add @ignoreClone to Transform._parentTransformCache Jun 15, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/Transform.ts`:
- Line 567: The _parentChange() method at the specified location delegates to
_updateAllWorldFlag, which has an early exit optimization that prevents it from
recursively invalidating descendants when the modification flags are already
set. This causes stale worldMatrix caches to persist after reparent operations.
Replace the call to _updateAllWorldFlag with a method that unconditionally
propagates invalidation to all descendants regardless of whether the flags are
currently set, ensuring descendants receive the reparent invalidation even if
the parent's flags were already marked as modified.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7c67b07a-14e2-42ba-ba78-6f6d0dc04002

📥 Commits

Reviewing files that changed from the base of the PR and between ac3a325 and 147d178.

📒 Files selected for processing (2)
  • packages/core/src/Transform.ts
  • tests/src/core/Transform.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/Transform.ts`:
- Line 567: The _parentChange() method at the specified location delegates to
_updateAllWorldFlag, which has an early exit optimization that prevents it from
recursively invalidating descendants when the modification flags are already
set. This causes stale worldMatrix caches to persist after reparent operations.
Replace the call to _updateAllWorldFlag with a method that unconditionally
propagates invalidation to all descendants regardless of whether the flags are
currently set, ensuring descendants receive the reparent invalidation even if
the parent's flags were already marked as modified.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7c67b07a-14e2-42ba-ba78-6f6d0dc04002

📥 Commits

Reviewing files that changed from the base of the PR and between ac3a325 and 147d178.

📒 Files selected for processing (2)
  • packages/core/src/Transform.ts
  • tests/src/core/Transform.test.ts
🛑 Comments failed to post (1)
packages/core/src/Transform.ts (1)

567-567: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reparent invalidation still short-circuits descendant propagation.

At Line 567, _parentChange() still delegates to _updateAllWorldFlag(...), but _updateAllWorldFlag (Line 770+) exits early when current flags are already set, which prevents recursive invalidation of descendants. This directly leaves stale worldMatrix caches reachable after reparent in the scenario described by this PR.

Suggested fix
  _parentChange(): void {
    this._isParentDirty = true;
-   this._updateAllWorldFlag(TransformModifyFlags.WmWpWeWqWsWus);
+   this._propagateReparentDirty(TransformModifyFlags.WmWpWeWqWsWus);
  }

+ private _propagateReparentDirty(flags: TransformModifyFlags): void {
+   this._isParentDirty = true;
+   this._worldAssociatedChange(flags);
+   const children = this._entity._children;
+   for (let i = 0, n = children.length; i < n; i++) {
+     children[i].transform?._propagateReparentDirty(flags);
+   }
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  _parentChange(): void {
    this._isParentDirty = true;
    this._propagateReparentDirty(TransformModifyFlags.WmWpWeWqWsWus);
  }

  private _propagateReparentDirty(flags: TransformModifyFlags): void {
    this._isParentDirty = true;
    this._worldAssociatedChange(flags);
    const children = this._entity._children;
    for (let i = 0, n = children.length; i < n; i++) {
      children[i].transform?._propagateReparentDirty(flags);
    }
  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/Transform.ts` at line 567, The _parentChange() method at
the specified location delegates to _updateAllWorldFlag, which has an early exit
optimization that prevents it from recursively invalidating descendants when the
modification flags are already set. This causes stale worldMatrix caches to
persist after reparent operations. Replace the call to _updateAllWorldFlag with
a method that unconditionally propagates invalidation to all descendants
regardless of whether the flags are currently set, ensuring descendants receive
the reparent invalidation even if the parent's flags were already marked as
modified.

GuoLei1990

This comment was marked as outdated.

@cptbtptpbcptdtptp cptbtptpbcptdtptp marked this pull request as draft June 16, 2026 08:02
Reproduces the real trigger: a component reading worldMatrix inside
_cloneTo (as DynamicCollider does) resolves a parent's _parentTransformCache
before the parent transform's cache is cloned. Without the fix the copy
stomps it back to the source's null while _isParentDirty stays false, so the
node renders at the origin after reparent. Fails on dev/2.0, passes with this PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cptbtptpbcptdtptp

Copy link
Copy Markdown
Collaborator Author

Root cause

After clone() + reparent, Transform._parentTransformCache can end up null while _isParentDirty === false. Since _getParentTransform() trusts _isParentDirty === false and returns the cache as-is, worldMatrix falls back to the local matrix and the node renders at the world origin (0, 0).

How the inconsistency is created (during clone)

_parentTransformCache and _isParentDirty were treated asymmetrically by the cloner:

  1. entity.clone()_parseCloneEntity clones children before the parent's own components. If any component reads worldMatrix during clone, that read resolves the parent's _parentTransformCache and sets _isParentDirty = false. In the real case this is DynamicCollider._cloneTo_syncNative_addNativeShape, which reads lossyWorldScale (captured call stack):
_getParentTransform
← UITransform.get (worldMatrix / lossyWorldScale)
← UITransform._getScaleMatrix
← DynamicCollider._addNativeShape
← DynamicCollider._syncNative
← DynamicCollider._cloneTo
  1. The parent transform's components are then cloned. _parentTransformCache (previously undecorated, so it was cloned) is copied from the source — whose value is null (a pooled prefab template that was never rendered) — overwriting the value resolved in step 1.
  2. _isParentDirty is @ignoreClone, so it is not copied and stays at the false from step 1.

➡️ Result: _parentTransformCache === null and _isParentDirty === false — a cache that claims to be valid but is null, and is never revalidated.

Why it surfaces

_parentChange on reparent only marks the directly-reparented node dirty, not its descendants, so the stale (null, false) state survives addChild. On the next worldMatrix read _getParentTransform() returns nullworldMatrix = localMatrix → the node renders at the origin.

Real-world manifestation: a pooled-prefab game (Screw) whose level layers carry DynamicColliders — after pool.get()/instantiate() + addChild, the layers render at the screen origin (reported on level 2).

Why the fix works

@ignoreClone on _parentTransformCache makes the two fields symmetric: the cache is no longer copied during clone, so it keeps the value resolved in step 1 (consistent with _isParentDirty === false). The companion _propagateReparentDirty change additionally re-dirties the whole subtree on reparent, so any already-stale descendant cache gets revalidated. Either change alone fixes the repro; together they restore and enforce the invariant "_isParentDirty === false ⟹ cache is valid".

Test

Added to Transform.test.ts: "clone keeps correct world position when a component reads worldMatrix during clone". It reproduces the exact trigger (a component reading worldMatrix in _cloneTo, mirroring DynamicCollider) through public APIs, and asserts the cloned node follows its reparented ancestor. It fails on dev/2.0 (10 !== 1010) and passes with this PR.

Note: the pre-existing WorldMatrixListener test passes with or without the fix (the listener's read happens after the cache copy, so it re-resolves correctly) — it does not actually guard against this bug and can be removed in favor of the test above.

@cptbtptpbcptdtptp cptbtptpbcptdtptp marked this pull request as ready for review June 17, 2026 11:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/src/core/Transform.test.ts`:
- Around line 184-186: The test is incomplete as it only validates the x and y
translation components of the worldMatrix (elements[12] and elements[13]) but is
missing the z-coordinate assertion (elements[14]), while the earlier test
validates all three components. Add an expectation statement that asserts
world.elements[14] equals 0 to ensure complete and consistent validation of all
three translation coordinates, matching the thoroughness of the first test case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1f284098-797a-4afc-86d3-ae364cd78103

📥 Commits

Reviewing files that changed from the base of the PR and between 147d178 and d597e88.

📒 Files selected for processing (1)
  • tests/src/core/Transform.test.ts

Comment on lines +184 to +186
const world = cloneLayer.transform.worldMatrix;
expect(world.elements[12]).to.equal(1010);
expect(world.elements[13]).to.equal(2020);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Consider asserting the z-coordinate for consistency and completeness.

The first test validates all three worldMatrix translation components (lines 151-153), but this test only checks elements[12] (x) and elements[13] (y). For consistency and complete coverage, consider adding:

expect(world.elements[14]).to.equal(0);

This ensures all three coordinates are validated and matches the thoroughness of the first test case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/src/core/Transform.test.ts` around lines 184 - 186, The test is
incomplete as it only validates the x and y translation components of the
worldMatrix (elements[12] and elements[13]) but is missing the z-coordinate
assertion (elements[14]), while the earlier test validates all three components.
Add an expectation statement that asserts world.elements[14] equals 0 to ensure
complete and consistent validation of all three translation coordinates,
matching the thoroughness of the first test case.

@GuoLei1990 GuoLei1990 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

总结

新增 commit d597e886(相对上轮 HEAD 147d17880 只多了 33 行测试,源码一行 @ignoreClone 未变)补了第二个测试 WorldReaderOnClone——一个在 _cloneTo 里读 worldMatrix 的 Script,忠实复刻了 DynamicCollider._cloneTo → _syncNative → _addNativeShapelossyWorldScale 的真实触发路径。

这正是我上两轮缺的那块拼图。 我用 PR HEAD 的 core dist 跑了反向证伪(CloneManager.getCloneMode(Transform) 运行时切换 _parentTransformCache 的 clone-mode:0=有 @ignoreClone / delete=无,等价 undecorated):

=== WITH @ignoreClone (fix) ===
  _cloneTo reads during clone: 1
  post-clone cloneLayer: _isParentDirty=false  cache=set
  worldMatrix tx/ty = [1010, 2020] => PASS (follows holder)

=== WITHOUT @ignoreClone (toggled, pre-fix) ===
  _cloneTo reads during clone: 1
  post-clone cloneLayer: _isParentDirty=false  cache=null   ← stale
  worldMatrix tx/ty = [10, 20]    => FAIL (falls back to local)

链路完全打通,我上轮的两条 P1 全部关闭

  • 上轮 [P1]「fix 是 no-op,构造不出失败态」—— 当时我的论证(clone 期间 listener 零 dispatch)对 listener 路径成立、现已复测仍 0 fire;但作者的真实路径是 _cloneTo,它由 ComponentCloner.cloneComponent(ComponentCloner.ts:40) 同步直接调,不依赖 dispatch,所以 clone 期间确实 fire(1 次读)。_parseCloneEntity(Entity.ts:483-490) 先递归 clone 整棵子树、后 clone 本节点组件——于是 leaf 的 _cloneToworldMatrix 时,父节点 layer 的 Transform 尚未被 clone,这次读 resolve 了 cloneLayer._parentTransformCache(设 _isParentDirty=false),随后 layer.Transform 被 clone、cloneProperty(CloneManager.ts:117) 对 null 源值走裸 assign 把已 resolve 的 cache 覆盖回 null → 留下 (cache=null, _isParentDirty=false) 的 stale 态。@ignoreClone 让 cloneProperty 在 :114 提前 return、不覆盖 → 修复成立。
  • 上轮 [P1]「测试不守回归」—— 新测试 revert @ignoreClone 后 FAIL、加回 PASS,断言是强形式(equal(1010) 而非「非 garbage」),真守回归

落点也对:root cause 是 _isParentDirty(@ignoreClone) 与 _parentTransformCache(未装饰) 在 cloner 眼里的不对称,一行让二者对称是本质解,非输出端擦屁股。非 null cache 那条本就走 Component._remap(Component.ts:160) 正确重映射,只有 null 源值会掉进裸 assign——所以这一行精准只补了真正破的那个 case。

整体可合。下面两条都不阻塞。

问题

[P2] tests/src/core/Transform.test.ts:127 第一个测试 WorldMatrixListener 不守回归,建议删除

我同样复测了它:clone 期间 listener 零次 fire(与上轮结论一致),revert @ignoreClone 后它照样 PASS(tx=1010)。它没在守本 bug——_updateFlagManager 的 listener 走的是 dispatch 路径,而 clone 期间 Transform 收尾用 _setDirtyFlagTrue(只 |= 不 dispatch),所以 listener 不触发、cache 不被 resolve、失败态根本构造不出来。作者本人在 PR 评论里也已确认「the pre-existing WorldMatrixListener test passes with or without the fix … can be removed in favor of the test above」。

既然 WorldReaderOnClone 已经真守回归,留着这个 0-fire 的 listener 测试只会给人「两个用例都在守 bug」的错觉、稀释信号。建议直接删掉,只留 WorldReaderOnClone 一个。(与上轮 :125/:155 那对是同性质问题,但指向的是本轮新代码,故重提一次。)

[P3] PR 描述的 Root cause 段落与真实机制不符 / 评论里的 _propagateReparentDirty 不在本 PR

  • PR body 的「Root cause」第 2 步写的是 listener 路径(「某个属性赋值触发 dirty dispatch → listener 读 worldMatrix」),而这条路径上面已证 clone 期间不 fire。真实机制是 _cloneTo 同步读——这一点 WorldReaderOnClone 的 inline 注释(:174-180)写得完全正确,但 PR body 仍停留在被证伪的 listener 理论。建议把 body 的 Root cause 更新成与测试注释一致的 _cloneTo 版本,免得后人对照 body 复现失败。
  • 2026-06-17 的评论里「The companion _propagateReparentDirty change additionally re-dirties the whole subtree on reparent」——这个 _propagateReparentDirty 改动在上一轮已被整体 revert,不在当前 diff 里(git diff 147d17880 d597e886 --stat 只有测试文件)。当前 PR 只有「一行 @ignoreClone」单一 fix,没有 companion 改动。评论这句会让 reviewer 误以为 reparent 侧也改了,建议订正措辞。

简化建议

无源码侧简化(一行 fix 已是最小形态,落点正确)。测试侧如 [P2]:删掉不守回归的 WorldMatrixListener,只留 WorldReaderOnClone 这一个真正反向证伪的用例。

@GuoLei1990 GuoLei1990 merged commit 3950676 into dev/2.0 Jun 20, 2026
12 checks passed
@GuoLei1990 GuoLei1990 added the bug Something isn't working label Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants