diff --git a/@plotly/dash-test-components/src/components/ArrayOfExactOrShapeWithNodePropAssignNone.js b/@plotly/dash-test-components/src/components/ArrayOfExactOrShapeWithNodePropAssignNone.js
new file mode 100644
index 0000000000..9e01f9b730
--- /dev/null
+++ b/@plotly/dash-test-components/src/components/ArrayOfExactOrShapeWithNodePropAssignNone.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const ArrayOfExactOrShapeWithNodePropAssignNone = (props) => {
+ const { id, test_array_of_exact_prop, test_array_of_shape_prop } = props;
+
+ return (
+
+ {`length of test_array_of_exact_prop: ${(test_array_of_exact_prop || []).length}, length of test_array_of_shape_prop: ${(test_array_of_shape_prop || []).length}`}
+
+ );
+};
+
+ArrayOfExactOrShapeWithNodePropAssignNone.propTypes = {
+ id: PropTypes.string,
+ test_array_of_exact_prop: PropTypes.arrayOf(
+ PropTypes.exact({
+ label: PropTypes.node,
+ value: PropTypes.string
+ })
+ ),
+ test_array_of_shape_prop: PropTypes.arrayOf(
+ PropTypes.shape({
+ label: PropTypes.node,
+ value: PropTypes.string
+ })
+ )
+};
+
+export default ArrayOfExactOrShapeWithNodePropAssignNone;
diff --git a/@plotly/dash-test-components/src/index.js b/@plotly/dash-test-components/src/index.js
index 76e88310a8..bdddfc18b5 100644
--- a/@plotly/dash-test-components/src/index.js
+++ b/@plotly/dash-test-components/src/index.js
@@ -12,6 +12,7 @@ import DrawCounter from './components/DrawCounter';
import AddPropsComponent from "./components/AddPropsComponent";
import ReceivePropsComponent from "./components/ReceivePropsComponent";
import ShapeOrExactKeepOrderComponent from "./components/ShapeOrExactKeepOrderComponent";
+import ArrayOfExactOrShapeWithNodePropAssignNone from './components/ArrayOfExactOrShapeWithNodePropAssignNone';
export {
@@ -27,5 +28,6 @@ export {
DrawCounter,
AddPropsComponent,
ReceivePropsComponent,
- ShapeOrExactKeepOrderComponent
+ ShapeOrExactKeepOrderComponent,
+ ArrayOfExactOrShapeWithNodePropAssignNone
};
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5237b2687b..f0de006ace 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## Fixed
- [#2994](https://github.com/plotly/dash/pull/2994) Keep generated doc-string order for shape or exact props. Fixes [#2990](https://github.com/plotly/dash/issues/2990)
+- [#3011](https://github.com/plotly/dash/pull/3011) Fixed an exception error caused by assigning `None` to array properties with `exact` or `shape` element types. Fixes [#3010](https://github.com/plotly/dash/issues/3010)
## [2.18.1] - 2024-09-12
diff --git a/dash/dash-renderer/src/TreeContainer.js b/dash/dash-renderer/src/TreeContainer.js
index 357c24d5b2..25b51bc493 100644
--- a/dash/dash-renderer/src/TreeContainer.js
+++ b/dash/dash-renderer/src/TreeContainer.js
@@ -322,7 +322,7 @@ class BaseTreeContainer extends Component {
});
node = rpath(frontPath, props);
- if (node === undefined || !node.length) {
+ if (node === undefined || !node?.length) {
continue;
}
const firstNode = rpath(backPath, node[0]);
diff --git a/tests/integration/renderer/test_array_of_exact_or_shape_with_node_prop_assign_none.py b/tests/integration/renderer/test_array_of_exact_or_shape_with_node_prop_assign_none.py
new file mode 100644
index 0000000000..ddfd8f86e1
--- /dev/null
+++ b/tests/integration/renderer/test_array_of_exact_or_shape_with_node_prop_assign_none.py
@@ -0,0 +1,31 @@
+from dash import Dash, html
+
+from dash_test_components import ArrayOfExactOrShapeWithNodePropAssignNone
+
+
+def test_aoeoswnpsn001_array_of_exact_or_shape_with_node_prop_assign_none(dash_duo):
+ app = Dash(__name__)
+ app.layout = html.Div(
+ [
+ ArrayOfExactOrShapeWithNodePropAssignNone(
+ id="test-component1",
+ test_array_of_exact_prop=[{"label": c, "value": c} for c in "abc"],
+ test_array_of_shape_prop=[{"label": c, "value": c} for c in "abc"],
+ ),
+ ArrayOfExactOrShapeWithNodePropAssignNone(
+ id="test-component2",
+ test_array_of_exact_prop=None,
+ test_array_of_shape_prop=None,
+ ),
+ ]
+ )
+
+ dash_duo.start_server(app)
+ dash_duo.wait_for_text_to_equal(
+ "#test-component1",
+ "length of test_array_of_exact_prop: 3, length of test_array_of_shape_prop: 3",
+ )
+ dash_duo.wait_for_text_to_equal(
+ "#test-component2",
+ "length of test_array_of_exact_prop: 0, length of test_array_of_shape_prop: 0",
+ )