Repository: Automattic/mongoose (2025-06-26T15:32:18Z)

Issue:
Getting error about unsupported SchemaType using .toJSONSchema({ useBsonType: true })
### Prerequisites

- [x] I have written a descriptive issue title

### Mongoose version

8.16.0

### Node.js version

20.19.0

### MongoDB version

8.0.6

### Operating system

Linux

### Operating system version (i.e. 20.04, 11.3, 10)

Ubuntu 22.04.5 LTS

### Issue

Hi, i wanted to make a exporter that will allow me to create Diagram in PlantUML but in this case one model is giving me an error `Converting unsupported SchemaType to JSON Schema: Mixed`.

Here below is code for this model (changed variables for privacy):
```JavaScript
import mongoose from 'mongoose'

const xFields = {
  procent: { type: Number, default: 0, min: 0, max: 100 },
  offset: { type: Number, default: 0 },
  cumulated: { type: Number, default: 0 },
}

const xSchema = new mongoose.Schema(
  {
    X: xFields, 
    XX: xFields, 
    XXX: xFields, 
    XXXX: xFields, 
    XXXXX: xFields, 
    XXXXXX: xFields, 
  },
  { _id: false },
)

const yFields = {
  start: { type: Number, default: 0 },
  end: { type: Number, default: 0 },
  duration: { type: Number, default: 0 },
  value: { type: Number, default: 0 },
  week: { type: Object, default: {} },
}

const ySchema = new mongoose.Schema(
  {
    Y: yFields,
    YY: yFields,
    YYY: yFields,
    YYYY: yFields,
    YYYYY: yFields,
    YYYYYY: yFields,
    YYYYYYY: yFields,
  },
  { _id: false },
)

const cFSchema = new mongoose.Schema(
  {
    revision: { type: mongoose.Schema.Types.ObjectId, ref: 'Revision', required: true },
    X: xSchema,
    Y: ySchema,
    Z: { type: Number, required: true, default: 0 },
  },
  { timestamps: true, optimisticConcurrency: true, collection: 'cf' },
)

cFSchema.index({ revision: 1 }, { unique: true })

const CF = mongoose.model('CF', cFSchema)

export default CF
```

Also is it possible to get a `entity-relationship` alike parameter of some sort


Discussion:

Patch:
diff --git a/.eslintrc.js b/.eslintrc.js
index 42772b93a6b..28b1225811f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -77,28 +77,6 @@ module.exports = {
         browser: true
       }
     }
-    // // eslint-plugin-markdown has been disabled because of out-standing issues, see https://github.com/eslint/eslint-plugin-markdown/issues/214
-    // {
-    //   files: ['**/*.md'],
-    //   processor: 'markdown/markdown'
-    // },
-    // {
-    //   files: ['**/*.md/*.js', '**/*.md/*.javascript', '**/*.md/*.ts', '**/*.md/*.typescript'],
-    //   parserOptions: {
-    //     ecmaFeatures: {
-    //       impliedStrict: true
-    //     },
-    //     sourceType: 'module', // required to allow "import" statements
-    //     ecmaVersion: 'latest' // required to allow top-level await
-    //   },
-    //   rules: {
-    //     'no-undef': 'off',
-    //     'no-unused-expressions': 'off',
-    //     'no-unused-vars': 'off',
-    //     'no-redeclare': 'off',
-    //     '@typescript-eslint/no-redeclare': 'off'
-    //   }
-    // }
   ],
   plugins: [
     'mocha-no-only'
diff --git a/lib/schema/mixed.js b/lib/schema/mixed.js
index a645a981f7b..bdb5f8d405b 100644
--- a/lib/schema/mixed.js
+++ b/lib/schema/mixed.js
@@ -124,6 +124,19 @@ SchemaMixed.prototype.castForQuery = function($cond, val) {
   return val;
 };
 
+/**
+ * Returns this schema type's representation in a JSON schema.
+ *
+ * @param [options]
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
+ * @returns {Object} JSON schema properties
+ */
+
+// eslint-disable-next-line no-unused-vars
+SchemaMixed.prototype.toJSONSchema = function toJSONSchema(_options) {
+  return {};
+};
+
 /*!
  * Module exports.
  */
diff --git a/lib/schemaType.js b/lib/schemaType.js
index 5b2951e222a..c97efc6df32 100644
--- a/lib/schemaType.js
+++ b/lib/schemaType.js
@@ -1779,8 +1779,9 @@ SchemaType.prototype._duplicateKeyErrorMessage = null;
  * @returns {Object} JSON schema properties
  */
 
-SchemaType.prototype.toJSONSchema = function toJSONSchema() {
-  throw new Error('Converting unsupported SchemaType to JSON Schema: ' + this.instance);
+// eslint-disable-next-line no-unused-vars
+SchemaType.prototype.toJSONSchema = function toJSONSchema(_options) {
+  throw new Error(`Converting unsupported SchemaType to JSON Schema: ${this.instance} at path "${this.path}"`);
 };
 
 /**


Test patch:
diff --git a/test/schema.test.js b/test/schema.test.js
index a012376d28a..00eecb46ba0 100644
--- a/test/schema.test.js
+++ b/test/schema.test.js
@@ -3341,7 +3341,8 @@ describe('schema', function() {
           type: String,
           required: function() { return this.age != null; },
           enum: ['document', 'self-reported']
-        }
+        },
+        any: Object
       }, { autoCreate: false, autoIndex: false });
 
       assert.deepStrictEqual(schema.toJSONSchema({ useBsonType: true }), {
@@ -3359,7 +3360,8 @@ describe('schema', function() {
           ageSource: {
             bsonType: ['string', 'null'],
             enum: ['document', 'self-reported', null]
-          }
+          },
+          any: {}
         }
       });
 
@@ -3379,7 +3381,8 @@ describe('schema', function() {
           ageSource: {
             type: ['string', 'null'],
             enum: ['document', 'self-reported', null]
-          }
+          },
+          any: {}
         }
       });
 
@@ -3390,18 +3393,21 @@ describe('schema', function() {
       });
       const Test = db.model('Test', schema, collectionName);
 
-      const doc1 = await Test.create({ name: 'Taco' });
+      const doc1 = await Test.create({ name: 'Taco', any: null });
       assert.equal(doc1.name, 'Taco');
+      assert.strictEqual(doc1.any, null);
 
-      const doc2 = await Test.create({ name: 'Billy', age: null, ageSource: null });
+      const doc2 = await Test.create({ name: 'Billy', age: null, ageSource: null, any: 42 });
       assert.equal(doc2.name, 'Billy');
       assert.strictEqual(doc2.age, null);
       assert.strictEqual(doc2.ageSource, null);
+      assert.strictEqual(doc2.any, 42);
 
-      const doc3 = await Test.create({ name: 'John', age: 30, ageSource: 'document' });
+      const doc3 = await Test.create({ name: 'John', age: 30, ageSource: 'document', any: { foo: 'bar' } });
       assert.equal(doc3.name, 'John');
       assert.equal(doc3.age, 30);
       assert.equal(doc3.ageSource, 'document');
+      assert.deepStrictEqual(doc3.any, { foo: 'bar' });
 
       await assert.rejects(
         Test.create([{ name: 'Foobar', age: null, ageSource: 'something else' }], { validateBeforeSave: false }),
@@ -3879,15 +3885,6 @@ describe('schema', function() {
         }
       });
     });
-
-    it('throws error on mixed type', function() {
-      const schema = new Schema({
-        mixed: mongoose.Mixed
-      });
-
-      assert.throws(() => schema.toJSONSchema({ useBsonType: true }), /unsupported SchemaType to JSON Schema: Mixed/);
-      assert.throws(() => schema.toJSONSchema(), /unsupported SchemaType to JSON Schema: Mixed/);
-    });
   });
 
   it('path() clears existing child schemas (gh-15253)', async function() {