nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: DevExpress/devextreme-vue
Pull request #45 (2018-04-18 16:29:34)

Fix acceptable values type check


Patch:
diff --git a/tools/src/component-generator.ts b/tools/src/component-generator.ts
index 0c67c16..1c7074a 100644
--- a/tools/src/component-generator.ts
+++ b/tools/src/component-generator.ts
@@ -22,6 +22,7 @@ interface IProp {
     name: string;
     types?: string[];
     acceptableValues?: string[];
+    acceptableValueType?: string;
     isArray?: boolean;
 }
 
@@ -74,7 +75,7 @@ const renderSimpleProp: (model: IProp) => string = createTempate(`
 const renderExtendedProp: (model: IProp) => string = createTempate(`
     <#= it.name #>: {<#? it.types #>
       type: <#? it.types.length > 1 #>[<#?#><#= it.types.join(', ') #><#? it.types.length > 1 #>]<#?#><#?#><#? it.acceptableValues #>,
-      validator: (v) => <#? it.isArray #>!Array.isArray(v) || v.filter(i => [<#= it.acceptableValues.join(', ') #>].indexOf(i) === -1).length === 0<#??#>typeof(v) !== "string" || [<#= it.acceptableValues.join(', ') #>].indexOf(v) !== -1<#?#>
+      validator: (v) => <#? it.isArray #>!Array.isArray(v) || v.filter(i => [<#= it.acceptableValues.join(', ') #>].indexOf(i) === -1).length === 0<#??#>typeof(v) !== <#? it.acceptableValueType #>"<#= it.acceptableValueType #>"<#??#>"string"<#?#> || [<#= it.acceptableValues.join(', ') #>].indexOf(v) !== -1<#?#>
     <#?#>}
 `.trimRight());
 // tslint:enable:max-line-length
diff --git a/tools/src/generator.ts b/tools/src/generator.ts
index 1037513..7b99f2e 100644
--- a/tools/src/generator.ts
+++ b/tools/src/generator.ts
@@ -52,7 +52,8 @@ function mapProp(rawOption: IOption): IProp {
     name: rawOption.name,
     acceptableValues: rawOption.valueRestriction && rawOption.valueRestriction.acceptableValues,
     types,
-    isArray: types && types.length === 1 && types[0] === "Array"
+    isArray: types && types.length === 1 && types[0] === "Array",
+    acceptableValueType: rawOption.valueRestriction && rawOption.valueRestriction.type.toLowerCase()
   };
 }
 


Test patch:
diff --git a/tools/src/component-generator.test.ts b/tools/src/component-generator.test.ts
index a34c9d4..6472c9c 100644
--- a/tools/src/component-generator.test.ts
+++ b/tools/src/component-generator.test.ts
@@ -165,6 +165,10 @@ const DxCLASS_NAME: VueConstructor = Vue.extend({
     PROP1: {
       type: TYPE1,
       validator: (v) => typeof(v) !== "string" || ["VAL1", "VAL2"].indexOf(v) !== -1
+    },
+    PROP2: {
+      type: TYPE2,
+      validator: (v) => typeof(v) !== "TYPE3" || ["VAL1", "VAL2"].indexOf(v) !== -1
     }
   },
   computed: {
@@ -190,6 +194,12 @@ export { DxCLASS_NAME };
                         name: "PROP1",
                         types: ["TYPE1"],
                         acceptableValues: [`"VAL1"`, `"VAL2"`]
+                    },
+                    {
+                        name: "PROP2",
+                        types: ["TYPE2"],
+                        acceptableValues: [`"VAL1"`, `"VAL2"`],
+                        acceptableValueType: "TYPE3"
                     }
                 ]
             })
Repository: DevExpress/devextreme-vue
Pull request #161 (2018-10-09 11:44:57)

Switch off inheritAttrs


Patch:
diff --git a/src/core/component.ts b/src/core/component.ts
index c48b7eb..48efa58 100644
--- a/src/core/component.ts
+++ b/src/core/component.ts
@@ -18,6 +18,8 @@ const DX_REMOVE_EVENT = "dxremove";
 
 const BaseComponent: VueConstructor = Vue.extend({
 
+    inheritAttrs: false,
+
     render(createElement: (...args) => VNode): VNode {
         return createElement(
             "div",


Test patch:
diff --git a/src/core/component.test.ts b/src/core/component.test.ts
index d16269c..948ceed 100644
--- a/src/core/component.test.ts
+++ b/src/core/component.test.ts
@@ -55,6 +55,11 @@ describe("component rendering", () => {
         expect(WidgetClass).toHaveBeenCalledTimes(1);
     });
 
+    it("component has disabled inheritAttrs", () => {
+        const component = new TestComponent();
+        expect(component.$options.inheritAttrs).toBe(false);
+    });
+
     it("creates nested component", () => {
         new Vue({
             template: "<test-component><test-component/></test-component>",
Repository: DevExpress/devextreme-vue
Pull request #182 (2018-10-29 15:46:53)

Pass id to inner element


Patch:
diff --git a/src/core/component.ts b/src/core/component.ts
index 8b17ea3..3a003fd 100644
--- a/src/core/component.ts
+++ b/src/core/component.ts
@@ -21,9 +21,11 @@ const BaseComponent: VueConstructor = Vue.extend({
     inheritAttrs: false,
 
     render(createElement: (...args) => VNode): VNode {
-        return createElement(
-            "div",
-            extractChildren(this.$slots.default, (this as any as IWidgetComponent).$_config)
+        return createElement("div", {
+                attrs: {
+                    id: this.$attrs.id
+                }
+            }, extractChildren(this.$slots.default, (this as any as IWidgetComponent).$_config)
         );
     },
 


Test patch:
diff --git a/src/core/component.test.ts b/src/core/component.test.ts
index 0933fb5..1a2f24f 100644
--- a/src/core/component.test.ts
+++ b/src/core/component.test.ts
@@ -80,6 +80,17 @@ describe("component rendering", () => {
         expect(component.$options.inheritAttrs).toBe(false);
     });
 
+    it("passes id to element", () => {
+        const vm = new Vue({
+            template: "<test-component id='my-id'/>",
+            components: {
+                TestComponent
+            }
+        }).$mount();
+
+        expect(vm.$el.id).toBe("my-id");
+    });
+
     it("creates nested component", () => {
         new Vue({
             template: "<test-component><test-component/></test-component>",
Repository: DevExpress/devextreme-vue
Pull request #183 (2018-10-30 08:04:56)

Pass id to inner element


Patch:
diff --git a/src/core/component.ts b/src/core/component.ts
index 8b17ea3..3a003fd 100644
--- a/src/core/component.ts
+++ b/src/core/component.ts
@@ -21,9 +21,11 @@ const BaseComponent: VueConstructor = Vue.extend({
     inheritAttrs: false,
 
     render(createElement: (...args) => VNode): VNode {
-        return createElement(
-            "div",
-            extractChildren(this.$slots.default, (this as any as IWidgetComponent).$_config)
+        return createElement("div", {
+                attrs: {
+                    id: this.$attrs.id
+                }
+            }, extractChildren(this.$slots.default, (this as any as IWidgetComponent).$_config)
         );
     },
 


Test patch:
diff --git a/src/core/component.test.ts b/src/core/component.test.ts
index 03afe99..0eb9e27 100644
--- a/src/core/component.test.ts
+++ b/src/core/component.test.ts
@@ -80,6 +80,17 @@ describe("component rendering", () => {
         expect(component.$options.inheritAttrs).toBe(false);
     });
 
+    it("passes id to element", () => {
+        const vm = new Vue({
+            template: "<test-component id='my-id'/>",
+            components: {
+                TestComponent
+            }
+        }).$mount();
+
+        expect(vm.$el.id).toBe("my-id");
+    });
+
     it("creates nested component", () => {
         new Vue({
             template: "<test-component><test-component/></test-component>",
Repository: DevExpress/devextreme-vue
Pull request #191 (2018-11-07 13:06:33)

Fix list hanging on selectionMode change


Patch:
diff --git a/src/core/configuration.ts b/src/core/configuration.ts
index a1fd3a6..9b5f153 100644
--- a/src/core/configuration.ts
+++ b/src/core/configuration.ts
@@ -1,4 +1,5 @@
 import { Vue } from "vue/types/vue";
+import { isEqual } from "./helpers";
 
 type UpdateFunc = (name: string, value: any) => void;
 
@@ -167,7 +168,9 @@ function subscribeOnUpdates(config: Configuration, vueInstance: Pick<Vue, "$emit
         } else if (args.fullName !== args.name) {
             optionValue = args.component.option(optionName);
         }
-        vueInstance.$emit("update:" + optionName, optionValue);
+        if (!isEqual(args.value, args.previousValue)) {
+            vueInstance.$emit("update:" + optionName, optionValue);
+        }
     };
 }
 
diff --git a/src/core/helpers.ts b/src/core/helpers.ts
index 257128a..e75def2 100644
--- a/src/core/helpers.ts
+++ b/src/core/helpers.ts
@@ -13,3 +13,15 @@ export function camelize(value: string): string {
 export function toComparable(value: any): any {
     return value instanceof Date ? value.getTime() : value;
 }
+
+export function isEqual(value1, value2) {
+    if (toComparable(value1) === toComparable(value2)) {
+        return true;
+    }
+
+    if (Array.isArray(value1)) {
+        return value1.length === 0 && value2.length === 0;
+    }
+
+    return false;
+}


Test patch:
diff --git a/src/core/configuration.test.ts b/src/core/configuration.test.ts
index 33bf6d1..291c3d2 100644
--- a/src/core/configuration.test.ts
+++ b/src/core/configuration.test.ts
@@ -166,6 +166,24 @@ it("subscribes on nested updates in root component", () => {
     expect(emitStub).toHaveBeenCalledWith("update:widgetOption", "widgetOptionValue");
 });
 
+it("subscribeOnUpdates does'not call update with empty array change", () => {
+    const emitStub = jest.fn();
+
+    const config: any = {
+        name: null
+    };
+
+    subscribeOnUpdates(
+        config,
+        {
+            $emit: emitStub
+        }
+    );
+    config.optionChangedFunc({name: "option1", fullName: "option1", value: [], previousValue: []});
+
+    expect(emitStub).toHaveBeenCalledTimes(0);
+});
+
 describe("initial configuration", () => {
 
     it("pulls value from nested", () => {
diff --git a/src/core/helpers.test.ts b/src/core/helpers.test.ts
index c04333c..8e50c4c 100644
--- a/src/core/helpers.test.ts
+++ b/src/core/helpers.test.ts
@@ -1,4 +1,4 @@
-import { toComparable } from "./helpers";
+import { isEqual, toComparable } from "./helpers";
 
 describe("toComparable", () => {
 
@@ -16,3 +16,16 @@ describe("toComparable", () => {
         expect(toComparable(testDate)).toBe(testDate.getTime());
     });
 });
+
+describe("isEqual", () => {
+
+    it("Primitive", () => {
+        expect(isEqual(1, 1)).toBe(true);
+    });
+
+    it("Empty Array", () => {
+        const testArray1 = [];
+        const testArray2 = [];
+        expect(isEqual(testArray1, testArray2)).toBe(true);
+    });
+});
Repository: DevExpress/devextreme-vue
Pull request #192 (2018-11-07 13:19:16)

Fix list hanging on selectionMode change


Patch:
diff --git a/src/core/configuration.ts b/src/core/configuration.ts
index 5c3205b..c765165 100644
--- a/src/core/configuration.ts
+++ b/src/core/configuration.ts
@@ -1,4 +1,5 @@
 import { Vue } from "vue/types/vue";
+import { isEqual } from "./helpers";
 
 type UpdateFunc = (name: string, value: any) => void;
 
@@ -192,7 +193,9 @@ function subscribeOnUpdates(config: Configuration, vueInstance: Pick<Vue, "$emit
         } else if (args.fullName !== args.name) {
             optionValue = args.component.option(optionName);
         }
-        vueInstance.$emit("update:" + optionName, optionValue);
+        if (!isEqual(args.value, args.previousValue)) {
+            vueInstance.$emit("update:" + optionName, optionValue);
+        }
     };
 }
 
diff --git a/src/core/helpers.ts b/src/core/helpers.ts
index 257128a..e75def2 100644
--- a/src/core/helpers.ts
+++ b/src/core/helpers.ts
@@ -13,3 +13,15 @@ export function camelize(value: string): string {
 export function toComparable(value: any): any {
     return value instanceof Date ? value.getTime() : value;
 }
+
+export function isEqual(value1, value2) {
+    if (toComparable(value1) === toComparable(value2)) {
+        return true;
+    }
+
+    if (Array.isArray(value1)) {
+        return value1.length === 0 && value2.length === 0;
+    }
+
+    return false;
+}


Test patch:
diff --git a/src/core/configuration.test.ts b/src/core/configuration.test.ts
index a961c96..864d1a9 100644
--- a/src/core/configuration.test.ts
+++ b/src/core/configuration.test.ts
@@ -175,6 +175,24 @@ it("subscribes on nested updates in root component", () => {
     expect(emitStub).toHaveBeenCalledWith("update:widgetOption", "widgetOptionValue");
 });
 
+it("subscribeOnUpdates does'not call update with empty array change", () => {
+    const emitStub = jest.fn();
+
+    const config: any = {
+        name: null
+    };
+
+    subscribeOnUpdates(
+        config,
+        {
+            $emit: emitStub
+        }
+    );
+    config.optionChangedFunc({name: "option1", fullName: "option1", value: [], previousValue: []});
+
+    expect(emitStub).toHaveBeenCalledTimes(0);
+});
+
 describe("initial configuration", () => {
 
     it("pulls value from nested", () => {
diff --git a/src/core/helpers.test.ts b/src/core/helpers.test.ts
index c04333c..8e50c4c 100644
--- a/src/core/helpers.test.ts
+++ b/src/core/helpers.test.ts
@@ -1,4 +1,4 @@
-import { toComparable } from "./helpers";
+import { isEqual, toComparable } from "./helpers";
 
 describe("toComparable", () => {
 
@@ -16,3 +16,16 @@ describe("toComparable", () => {
         expect(toComparable(testDate)).toBe(testDate.getTime());
     });
 });
+
+describe("isEqual", () => {
+
+    it("Primitive", () => {
+        expect(isEqual(1, 1)).toBe(true);
+    });
+
+    it("Empty Array", () => {
+        const testArray1 = [];
+        const testArray2 = [];
+        expect(isEqual(testArray1, testArray2)).toBe(true);
+    });
+});
Repository: DevExpress/devextreme-vue
Pull request #203 (2018-11-12 08:55:23)

Fix previous value array check (#201)


Patch:
diff --git a/src/core/helpers.ts b/src/core/helpers.ts
index e75def2..5f2851f 100644
--- a/src/core/helpers.ts
+++ b/src/core/helpers.ts
@@ -19,7 +19,7 @@ export function isEqual(value1, value2) {
         return true;
     }
 
-    if (Array.isArray(value1)) {
+    if (Array.isArray(value1) && Array.isArray(value2)) {
         return value1.length === 0 && value2.length === 0;
     }
 


Test patch:
diff --git a/src/core/helpers.test.ts b/src/core/helpers.test.ts
index 8e50c4c..965d00b 100644
--- a/src/core/helpers.test.ts
+++ b/src/core/helpers.test.ts
@@ -28,4 +28,17 @@ describe("isEqual", () => {
         const testArray2 = [];
         expect(isEqual(testArray1, testArray2)).toBe(true);
     });
+
+    it("Empty Array and null", () => {
+        const testArray1 = [];
+        const testArray2 = null;
+        expect(isEqual(testArray1, testArray2)).toBe(false);
+        expect(isEqual(testArray2, testArray1)).toBe(false);
+    });
+
+    it("Date", () => {
+        const testDate1 = new Date(2018, 9, 9);
+        const testDate2 = new Date(2018, 9, 9);
+        expect(isEqual(testDate1, testDate2)).toBe(true);
+    });
 });
Repository: DevExpress/devextreme-vue
Pull request #204 (2018-11-12 08:55:41)

Fix previous value array check (#201)


Patch:
diff --git a/src/core/helpers.ts b/src/core/helpers.ts
index e75def2..5f2851f 100644
--- a/src/core/helpers.ts
+++ b/src/core/helpers.ts
@@ -19,7 +19,7 @@ export function isEqual(value1, value2) {
         return true;
     }
 
-    if (Array.isArray(value1)) {
+    if (Array.isArray(value1) && Array.isArray(value2)) {
         return value1.length === 0 && value2.length === 0;
     }
 


Test patch:
diff --git a/src/core/helpers.test.ts b/src/core/helpers.test.ts
index 8e50c4c..965d00b 100644
--- a/src/core/helpers.test.ts
+++ b/src/core/helpers.test.ts
@@ -28,4 +28,17 @@ describe("isEqual", () => {
         const testArray2 = [];
         expect(isEqual(testArray1, testArray2)).toBe(true);
     });
+
+    it("Empty Array and null", () => {
+        const testArray1 = [];
+        const testArray2 = null;
+        expect(isEqual(testArray1, testArray2)).toBe(false);
+        expect(isEqual(testArray2, testArray1)).toBe(false);
+    });
+
+    it("Date", () => {
+        const testDate1 = new Date(2018, 9, 9);
+        const testDate2 = new Date(2018, 9, 9);
+        expect(isEqual(testDate1, testDate2)).toBe(true);
+    });
 });
Repository: DevExpress/devextreme-vue
Pull request #262 (2019-04-26 11:33:46)

Switch `useLegacyTemplateEngine` to false (BC5079)


Patch:
diff --git a/example/app.vue b/example/app.vue
index a16cad0..2829401 100644
--- a/example/app.vue
+++ b/example/app.vue
@@ -46,9 +46,6 @@ import ChartExample from "./components/chart-example";
 import TabPanelExample from "./components/tab-panel-example";
 import FormExample from "./components/form-example";
 
-import config from "../src/core/config";
-config({ useLegacyTemplateEngine: false });
-
 export default {
     components: {
         AccessingInstanceExample,
diff --git a/src/core/config.ts b/src/core/config.ts
index 761f007..cbf874b 100644
--- a/src/core/config.ts
+++ b/src/core/config.ts
@@ -3,11 +3,11 @@ interface IOptions {
   }
 
 let config: IOptions = {
-    useLegacyTemplateEngine: true
+    useLegacyTemplateEngine: false
 };
 
 function setOptions(options: Partial<IOptions>): void {
-    config = {...config, ... options};
+    config = { ...config, ...options };
 }
 
 function getOption<TName extends keyof IOptions>(optionName: TName): IOptions[TName] {


Test patch:
diff --git a/src/core/component.test.ts b/src/core/component.test.ts
index c770123..22962e9 100644
--- a/src/core/component.test.ts
+++ b/src/core/component.test.ts
@@ -1,13 +1,10 @@
 import Vue, { VueConstructor } from "vue";
 import { DxComponent, IWidgetComponent } from "../core/component";
-import globalConfig from "../core/config";
 import { DxConfiguration, IConfigurable, IConfigurationComponent } from "../core/configuration-component";
 import { DxExtensionComponent } from "../core/extension-component";
 
 import * as events from "devextreme/events";
 
-globalConfig({ useLegacyTemplateEngine: false });
-
 const eventHandlers: { [index: string]: (e?: any) => void } = {};
 const Widget = {
     option: jest.fn(),
Repository: DevExpress/devextreme-vue
Pull request #322 (2019-09-27 11:20:06)

Fix component update by v-for directive
Cherry pick of #319 


Patch:
diff --git a/src/core/component.ts b/src/core/component.ts
index e111bd5..4ba06ea 100644
--- a/src/core/component.ts
+++ b/src/core/component.ts
@@ -273,6 +273,14 @@ function cleanWidgetNode(node: Node) {
     });
 }
 
+function restoreNodes(el: Element, nodes: Record<number, ChildNode>) {
+    for (const key in nodes) {
+        if (nodes.hasOwnProperty(key)) {
+            el.appendChild(nodes[key]);
+        }
+    }
+}
+
 const DxComponent: VueConstructor = BaseComponent.extend({
     methods: {
         $_getExtraIntegrationOptions(): object {
@@ -293,10 +301,13 @@ const DxComponent: VueConstructor = BaseComponent.extend({
     },
 
     mounted(): void {
+        const nodes = {...this.$el.childNodes};
         cleanWidgetNode(this.$el);
 
         this.$_createWidget(this.$el);
         this.$_instance.endUpdate();
+
+        restoreNodes(this.$el, nodes);
         this.$children.forEach((child: IVue) => {
             const childExtension = child as any as IExtension;
             if (childExtension.$_isExtension) {


Test patch:
diff --git a/src/core/component.test.ts b/src/core/component.test.ts
index 8107042..e07395b 100644
--- a/src/core/component.test.ts
+++ b/src/core/component.test.ts
@@ -1030,6 +1030,22 @@ describe("nested option", () => {
 
         expect(innerHtml).toBe("");
     });
+
+    it("restore nodes after widget creation (T800987)", () => {
+        const vm = new Vue({
+            template:
+                `<test-component>` +
+                `  <nested/>` +
+                `  <nested/>` +
+                `</test-component>`,
+            components: {
+                TestComponent,
+                Nested
+            }
+        }).$mount();
+
+        expect(vm.$el.childNodes.length).toBe(3);
+    });
 });
 
 function renderTemplate(name: string, model?: object, container?: any): Element {
Repository: DevExpress/devextreme-vue
Pull request #746 (2023-08-23 13:30:17)

Clear templates store when component does not have slots
Cherry pick of [#25422](https://github.com/DevExpress/DevExtreme/pull/25422)


Patch:
diff --git a/package.json b/package.json
index b8acec0..c5b61c2 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,7 @@
     "clean:packages": "npm run clean --yes --ws --if-present && npm run clean:root",
     "clean:root": "del-cli node_modules",
     "start:packages": "npn run start --ws --if-present",
-    "build:packages": "npm run build --ws --if-present",
+    "build:packages": "npm run build -w devextreme-vue-generator && npm run build --ws --if-present",
     "lint": "gulp lint",
     "test": "jest",
     "test-watch": "jest --watch",
diff --git a/packages/devextreme-vue/src/core/templates-manager.ts b/packages/devextreme-vue/src/core/templates-manager.ts
index ada0fd5..c8e7db2 100644
--- a/packages/devextreme-vue/src/core/templates-manager.ts
+++ b/packages/devextreme-vue/src/core/templates-manager.ts
@@ -21,13 +21,11 @@ class TemplatesManager {
     }
 
     public discover() {
-        const slots = discoverSlots(this._component);
         this._slots = {
-            ...this._slots,
-            ...slots
+            ...discoverSlots(this._component),
         };
 
-        if (!allKeysAreEqual(this._templates, slots)) {
+        if (!allKeysAreEqual(this._templates, this._slots)) {
             this._prepareTemplates();
         }
     }


Test patch:
diff --git a/packages/devextreme-vue/src/core/__tests__/templates-manager.test.ts b/packages/devextreme-vue/src/core/__tests__/templates-manager.test.ts
index 981e950..1ae1ce3 100644
--- a/packages/devextreme-vue/src/core/__tests__/templates-manager.test.ts
+++ b/packages/devextreme-vue/src/core/__tests__/templates-manager.test.ts
@@ -109,5 +109,17 @@ describe("TemplatesManager", () => {
 
             expect(Object.keys(templatesManager.templates)).toEqual(["template1", "template2"]);
         });
+
+        it("clear templates when we do not have slots", () => {
+            (discover as any).mockImplementationOnce(discoverMock3);
+
+            const templatesManager = new TemplatesManager(VueWrapper as any);
+
+            expect(Object.keys(templatesManager.templates)).toEqual(["template1", "template2"]);
+
+            (discover as any).mockImplementationOnce(discoverMock1);
+            templatesManager.discover();
+            expect(Object.keys(templatesManager.templates)).toEqual([]);
+        });
     });
 });
Repository: wix/Detox
Pull request #2594 (2021-01-15 12:06:12)

fix: bad attempt to dispose a not allocated device
- [x] This is a small change 

---

**Description:**

Started seeing the error like

```
SyntaxError: Unexpected token u in JSON at position 0
```

![Screenshot 2021-01-15 at 14 04 25](https://user-images.githubusercontent.com/1962469/104725434-c208ac00-573a-11eb-9971-c9ba948d0f62.png)


This PR fixes it.


Patch:
diff --git a/detox/src/devices/DeviceRegistry.js b/detox/src/devices/DeviceRegistry.js
index d46def564..02f6783d7 100644
--- a/detox/src/devices/DeviceRegistry.js
+++ b/detox/src/devices/DeviceRegistry.js
@@ -70,7 +70,9 @@ class DeviceRegistry {
   async disposeDevice(getDeviceHandle) {
     await this._lockfile.exclusively(async () => {
       const deviceId = await safeAsync(getDeviceHandle);
-      this._toggleDeviceStatus(deviceId, false);
+      if (deviceId) {
+        this._toggleDeviceStatus(deviceId, false);
+      }
     });
   }
 


Test patch:
diff --git a/detox/src/devices/DeviceRegistry.test.js b/detox/src/devices/DeviceRegistry.test.js
index 9f2e20487..39e33c402 100644
--- a/detox/src/devices/DeviceRegistry.test.js
+++ b/detox/src/devices/DeviceRegistry.test.js
@@ -224,6 +224,10 @@ describe('DeviceRegistry', () => {
       await expectNotIncludedInReadDevicesList(deviceHandleAsClassInstance);
     });
 
+    it('should not fail when there were no actual device to dispose', async () => {
+      await expect(disposeDevice(undefined)).resolves.not.toThrowError();
+    });
+
     describe('.reset() method', () => {
       it('should create a lock file with an empty array if it does not exist', async () => {
         expect(await fs.exists(lockfilePath)).toBe(false);