Repository: jsonata-js/jsonata (2026-07-15T15:35:12Z)

Issue:
Context variabe binding breaks when joining empty arrays or the join results in an empty result
Let's consider the following input:
```json
{
  "equipments": [
    {
      "type": "Type A",
      "name": "Name A"
    },
    {
      "type": "Type A",
      "name": "Name A2"
    },
    {
      "type": "Type B",
      "name": "Name B"
    }
  ],
  "data": [
    {
      "id": "0001",
      "equipmentName": "Name A"
    },
    {
      "id": "0001",
      "equipmentName": "Name A2",
      "value": 1
    },
    {
      "id": "0001",
      "equipmentName": "Name B",
      "value": 2
    },
    {
      "id": "0002",
      "equipmentName": "Name A",
      "value": 3
    },
    {
      "id": "0003",
      "equipmentName": "Name A2",
      "value": 3
    }
  ]
}
```

and the following Jsonata:

```jsonata
equipments@$equipments.data
  [$equipments.type = "Type A" and $equipments.name = equipmentName] {
  id: {
    "equipmentNames": equipmentName[]
  }
}
```

which correctly results in 
```json
{
  "0001": {
    "equipmentNames": [
      "Name A",
      "Name A2"
    ]
  },
  "0002": {
    "equipmentNames": [
      "Name A"
    ]
  },
  "0003": {
    "equipmentNames": [
      "Name A2"
    ]
  }
}
```

Now the issue is, if:
- in the input `equipments` is empty or does not exist
- or `data` is empty or does not exist
- or the filter `[ ... ]` (e.g. by changing `"Type A"` into `"Type C"`) returns an empty result

then the following error is thrown:

```
can't access property "@", c is undefined
```

It looks like a bug since the error message is not clear about what I did wrong.

I could add a `.` after the filter but this changes the result and messes up the grouping:

```jsonata
equipments@$equipments.data
  [$equipments.type = "Type A" and $equipments.name = equipmentName]. {
  id: {
    "equipmentNames": equipmentName[]
  }
}
```


Discussion:

Patch:
diff --git a/src/jsonata.js b/src/jsonata.js
index 82d2b018..184de406 100644
--- a/src/jsonata.js
+++ b/src/jsonata.js
@@ -924,7 +924,7 @@ var jsonata = (function() {
             input = focus.createSequence(input);
         }
         // if the array is empty, add an undefined entry to enable literal JSON object to be generated
-        if (input.length === 0) {
+        if (input.length === 0 && !reduce) {
             input.push(undefined);
         }
 


Test patch:
diff --git a/test/test-suite/groups/joins/library-joins.json b/test/test-suite/groups/joins/library-joins.json
index 03d34cd3..58a5f90f 100644
--- a/test/test-suite/groups/joins/library-joins.json
+++ b/test/test-suite/groups/joins/library-joins.json
@@ -196,5 +196,25 @@
                 "customer": "10003"
             }
         ]
+    },
+    {
+        "expr-file": "library-joins011.jsonata",
+        "dataset": "library",
+        "bindings": {},
+        "result": {
+            "Joe Doe": [
+                "Structure and Interpretation of Computer Programs"
+            ],
+            "Jason Arthur": [
+                "Compilers: Principles, Techniques, and Tools",
+                "Structure and Interpretation of Computer Programs"
+            ]
+        }
+    },
+    {
+        "expr-file": "library-joins012.jsonata",
+        "dataset": "library",
+        "bindings": {},
+        "result": {}
     }
 ]
diff --git a/test/test-suite/groups/joins/library-joins011.jsonata b/test/test-suite/groups/joins/library-joins011.jsonata
new file mode 100644
index 00000000..9943a024
--- /dev/null
+++ b/test/test-suite/groups/joins/library-joins011.jsonata
@@ -0,0 +1,3 @@
+library.loans@$L.books@$B[$L.isbn=$B.isbn].customers[$L.customer=id]{
+  name: $B.title[]
+}
\ No newline at end of file
diff --git a/test/test-suite/groups/joins/library-joins012.jsonata b/test/test-suite/groups/joins/library-joins012.jsonata
new file mode 100644
index 00000000..3fd78cd4
--- /dev/null
+++ b/test/test-suite/groups/joins/library-joins012.jsonata
@@ -0,0 +1,3 @@
+library.loans@$L.books@$B[$L.isbn=$B.isbn].customers[$L.customer='not found']{
+  name: $B.title[]
+}
\ No newline at end of file