Repository: usebruno/bruno (2026-03-30T14:29:47Z)

Issue:
Assert Section Signals Invalid JSON For Array With String Values
### I have checked the following:

- [x] I have searched existing issues and found nothing related to my issue.

### This bug is:

- [ ] making Bruno unusable for me
- [ ] slowing me down but I'm able to continue working
- [x] annoying
- [x] this feature was working in a previous version but is broken in the current release.

### Bruno version

3.1.4

### Operating System

macOS Tahoe 26.3.1 (a)

### Describe the bug

I usually have some basic assertions for all requests. I noticed that Bruno is failing a simple `res.body` `isJson` assertion now for some responses that are just a collection of string values; for instance:

```javascript
[
  "A55001213ZX0A"
]
```

### .bru file to reproduce the bug

```bru
meta {
  name: Some Identifier
  type: http
}

get {
  url: {{api-host}}/resource/{{resource-id}}
  body: none
}

headers {
  Accept: application/json
}

vars:pre-request {
  resource-id: A55001213ZX0A
}

assert {
  res.status: eq 200
  res.body: isJson
}
```

### Screenshots/Live demo link

N/A


Discussion:
<!-- This is an auto-generated issue plan by CodeRabbit -->
<details>
<summary>🔗 Related PRs</summary>

usebruno/bruno#6476 - fix: openapi spec with example values [merged]
usebruno/bruno#6488 - fix: JSON response examples being saved as [object Object] in YAML format [merged]
usebruno/bruno#7191 - fix: `isJson` assertion fails after `res.setBody()` with object in `node-vm` [merged]
usebruno/bruno#7207 - fix(cli): preserve request item type during import and fail on unsupported types [merged]
usebruno/bruno#7476 - fix: convert non-string variable values to strings during postman import [merged]
</details>

---
<details>
<summary>📝 Issue Planner</summary>

<sub>Check the box below or use the `@coderabbitai plan` command to generate an implementation plan and prompts that you can use with your favorite coding assistant.</sub>

- [ ] <!-- {"checkboxId": "8d4f2b9c-3e1a-4f7c-a9b2-d5e8f1c4a7b9"} --> Create Plan
</details>


---
<details>
<summary> 🧪 Issue enrichment is currently in open beta.</summary>


You can configure auto-planning by selecting labels in the issue_enrichment configuration.

To disable automatic issue enrichment, add the following to your `.coderabbit.yaml`:
```yaml
issue_enrichment:
  auto_enrich:
    enabled: false
```
</details>

💬 Have feedback or questions? Drop into our [discord](https://discord.gg/coderabbit)!



Patch:
diff --git a/packages/bruno-js/src/runtime/assert-runtime.js b/packages/bruno-js/src/runtime/assert-runtime.js
index c30f1eb65fb..1af9c338aad 100644
--- a/packages/bruno-js/src/runtime/assert-runtime.js
+++ b/packages/bruno-js/src/runtime/assert-runtime.js
@@ -17,8 +17,8 @@ chai.use(function (chai, utils) {
     // Objects created inside Node's vm.createContext() have a different Object constructor,
     // so obj.constructor === Object fails for objects passed via res.setBody() from scripts.
     // Note: toString check is more permissive than constructor check — custom class instances
-    const isJson = typeof obj === 'object' && obj !== null && !Array.isArray(obj)
-      && Object.prototype.toString.call(obj) === '[object Object]';
+    const isJson = typeof obj === 'object' && obj !== null
+      && (Array.isArray(obj) || Object.prototype.toString.call(obj) === '[object Object]');
 
     this.assert(isJson, `expected ${utils.inspect(obj)} to be JSON`, `expected ${utils.inspect(obj)} not to be JSON`);
   });


Test patch:
diff --git a/packages/bruno-js/src/sandbox/quickjs/shims/test.js b/packages/bruno-js/src/sandbox/quickjs/shims/test.js
index 12c6e5058f0..f7ef9085450 100644
--- a/packages/bruno-js/src/sandbox/quickjs/shims/test.js
+++ b/packages/bruno-js/src/sandbox/quickjs/shims/test.js
@@ -69,8 +69,8 @@ const addBruShimToContext = (vm, __brunoTestResults) => {
         Object.defineProperty(proto, 'json', {
           get: function () {
             var obj = this._obj;
-            var isJson = typeof obj === 'object' && obj !== null && !Array.isArray(obj) &&
-              Object.prototype.toString.call(obj) === '[object Object]';
+            var isJson = typeof obj === 'object' && obj !== null &&
+              (Array.isArray(obj) || Object.prototype.toString.call(obj) === '[object Object]');
             this.assert(isJson, 'expected #{this} to be JSON', 'expected #{this} not to be JSON');
             return this;
           },
diff --git a/packages/bruno-js/tests/runtime.spec.js b/packages/bruno-js/tests/runtime.spec.js
index 2ecc19f4e52..a925db847c3 100644
--- a/packages/bruno-js/tests/runtime.spec.js
+++ b/packages/bruno-js/tests/runtime.spec.js
@@ -317,12 +317,36 @@ describe('runtime', () => {
         expect(results[0].status).toBe('pass');
       });
 
-      it('should fail for an array', () => {
+      it('should pass for an array', () => {
         const results = runAssertions(
           [{ name: 'res.body', value: 'isJson', enabled: true }],
           makeResponse([1, 2, 3])
         );
-        expect(results[0].status).toBe('fail');
+        expect(results[0].status).toBe('pass');
+      });
+
+      it('should pass for an array of strings', () => {
+        const results = runAssertions(
+          [{ name: 'res.body', value: 'isJson', enabled: true }],
+          makeResponse(['A55001213ZX0A'])
+        );
+        expect(results[0].status).toBe('pass');
+      });
+
+      it('should pass for an empty array', () => {
+        const results = runAssertions(
+          [{ name: 'res.body', value: 'isJson', enabled: true }],
+          makeResponse([])
+        );
+        expect(results[0].status).toBe('pass');
+      });
+
+      it('should pass for an array of objects', () => {
+        const results = runAssertions(
+          [{ name: 'res.body', value: 'isJson', enabled: true }],
+          makeResponse([{ id: 1 }, { id: 2 }])
+        );
+        expect(results[0].status).toBe('pass');
       });
 
       it('should fail for a string', () => {