Skip to content

Conversation

rgunindi
Copy link

@rgunindi rgunindi commented Aug 24, 2025

Added a type check in mongoFieldToParseSchemaField to ensure type is a string before calling startsWith. This prevents crashes when Parse Server processes MongoDB schema fields with undefined, null, or unexpected type values.

Closes #9847

Pull Request

Issue

Approach

Tasks

  • Add tests

Summary by CodeRabbit

  • Bug Fixes

    • Improved schema validation for Mongo-backed storage: invalid, empty, or non-string field types now produce clear, user-facing errors instead of crashes.
  • Tests

    • Added comprehensive tests covering valid field-type mappings and verifying invalid inputs reliably throw the expected errors.
  • Chores

    • Strengthened input guards to reduce ambiguous failures and improve reliability during schema setup and migrations.

Copy link

parse-github-assistant bot commented Aug 24, 2025

🚀 Thanks for opening this pull request!

Copy link

coderabbitai bot commented Aug 24, 2025

📝 Walkthrough

Walkthrough

Adds input validation to mongoFieldToParseSchemaField to throw a Parse.Error when type is falsy or not a string; updates the caller to pass field and class names; adds tests covering valid mappings and invalid/non-string inputs. No public API signatures changed.

Changes

Cohort / File(s) Summary
Mongo schema field type validation
src/Adapters/Storage/Mongo/MongoSchemaCollection.js
Added an upfront input guard in mongoFieldToParseSchemaField(type, fieldName, className) that throws Parse.Error (code INVALID_SCHEMA_OPERATION) with a descriptive message when type is falsy or not a string; mapping logic remains unchanged. Updated call site to pass fieldName and schema._id.
Tests: mongoFieldToParseSchemaField
spec/MongoSchemaCollectionAdapter.spec.js
Added tests exercising mappings of many Mongo field type representations to Parse schema fields and tests asserting invalid inputs (null, undefined, non-string, empty string, numeric, boolean, object, array) throw Parse.Error with code 255 and message containing "Invalid field type".

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Init as Initializer
  participant MSC as MongoSchemaCollection
  participant Mapper as Mapping logic

  Init->>MSC: mongoFieldToParseSchemaField(type, fieldName, className)
  alt type is falsy or not a string
    MSC-->>Init: throw Parse.Error(INVALID_SCHEMA_OPERATION, "Invalid field type: ${type} for field '...'. Expected a string.")
  else
    MSC->>Mapper: evaluate mapping branches (relation<>, pointer, basic types, arrays, geo, file, bytes, polygon)
    Mapper-->>MSC: return parsed field descriptor
    MSC-->>Init: return parsed field descriptor
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Prevent TypeError by ensuring type is a string before calling startsWith (#9847) Validation prevents non-string type from reaching startsWith.
Handle malformed or unexpected schema type values gracefully on startup (#9847) Function now throws a controlled Parse.Error with a descriptive message instead of raising a TypeError.

Pre-merge checks (4 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately and directly summarizes the primary change: adding validation to prevent server crashes when a schema field's type is not a string, and it maps to the changes in MongoSchemaCollection.js and the added tests.
Linked Issues Check ✅ Passed The changes implement the coding objective from issue [#9847] by validating that schema field type is a string before using string methods, throwing a Parse.Error when it is not, updating the call site to pass field and class identifiers, and adding tests that assert correct mappings and error behavior, which satisfies the linked issue's requirements.
Out of Scope Changes Check ✅ Passed The diff and provided summaries show changes confined to MongoSchemaCollection.js and its spec file with no modifications to unrelated modules, so there are no detected out-of-scope changes outside the linked issue objectives.
Description Check ✅ Passed The description includes a clear summary of the fix, links the PR to issue #9847, and notes that tests were added, so it covers the core template requirements; however the repository template's "Approach" section is empty and could be populated with a brief description of the validation logic and error behavior.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Aug 24, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/Adapters/Storage/Mongo/MongoSchemaCollection.js (4)

54-55: Optional: add field context to the error for easier debugging

If we keep throwing inside mongoFieldToParseSchemaField, wrapping this call to append className/fieldName context improves operator UX when boot fails on bad schemas.

-    obj[fieldName] = mongoFieldToParseSchemaField(schema[fieldName]);
+    try {
+      obj[fieldName] = mongoFieldToParseSchemaField(schema[fieldName]);
+    } catch (e) {
+      if (e && e.code != null) {
+        // Preserve code; enrich message
+        e.message = `Invalid field type for "${fieldName}" in class "${schema._id}": ${e.message}`;
+      }
+      throw e;
+    }

5-11: Add regression tests for non-string/whitespace input types

To lock this down, please add tests covering:

  • type: undefined, null, number, boolean, object, array, function
  • type: '' and ' ' (whitespace)
  • type: 'number ' (trailing space) → with the trim change, should map to Number; without it, it silently fails

If helpful, I can draft a spec in spec/schemas.spec.js that exercises mongoSchemaFieldsToParseSchemaFields with a mocked schema input.


25-47: Add a default case in mongoFieldToParseSchemaField to reject unsupported types

I’ve confirmed that the only call site for mongoFieldToParseSchemaField is within mongoSchemaFieldsToParseSchemaFields, and no code relies on it returning undefined. Failing fast on unrecognized types will surface schema misconfigurations immediately without breaking existing behavior.

• File: src/Adapters/Storage/Mongo/MongoSchemaCollection.js
• Location: inside the switch (type) in mongoFieldToParseSchemaField

Recommended diff:

   switch (type) {
     // …existing cases…
     case 'polygon':
       return { type: 'Polygon' };
+    default:
+      throw new Parse.Error(
+        Parse.Error.INVALID_SCHEMA_OPERATION,
+        `Unsupported field type: "${type}".`
+      );
   }

5-13: Tighten type validation and normalize input

Great addition to guard against TypeError. Two optional hardening tweaks:

  • Reject empty or whitespace-only strings by using type.trim().
  • Trim type before downstream checks so trailing (or leading) spaces can’t sneak through.

Proposed diff in src/Adapters/Storage/Mongo/MongoSchemaCollection.js (lines 5–13):

   // Add type validation to prevent TypeError
-  if (!type || typeof type !== 'string') {
+  if (typeof type !== 'string' || type.trim() === '') {
     throw new Parse.Error(
       Parse.Error.INVALID_SCHEMA_OPERATION,
-      `Invalid field type: ${type}. Expected a string. Field type must be one of: string, number, boolean, date, map, object, array, geopoint, file, bytes, polygon, or a valid relation/pointer format.`
+      `Invalid field type: ${String(type)}. Expected a non-empty string. Field type must be one of: string, number, boolean, date, map, object, array, geopoint, file, bytes, polygon, or a valid relation/pointer format.`
     );
   }
+
+  // Normalize input
+  type = type.trim();

Follow-up question:

  • All other “invalid field type” guards (e.g. in SchemaController) use Parse.Error.INCORRECT_TYPE. Should we switch from INVALID_SCHEMA_OPERATION to INCORRECT_TYPE here for consistency?
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4b3f10b and 8d90d30.

📒 Files selected for processing (1)
  • src/Adapters/Storage/Mongo/MongoSchemaCollection.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/Adapters/Storage/Mongo/MongoSchemaCollection.js (7)
spec/schemas.spec.js (1)
  • Parse (3-3)
src/Controllers/SchemaController.js (1)
  • Parse (18-18)
src/Adapters/Auth/apple.js (1)
  • Parse (48-48)
src/Adapters/Auth/facebook.js (1)
  • Parse (62-62)
src/Adapters/Auth/ldap.js (1)
  • Parse (77-77)
src/SchemaMigrations/DefinedSchemas.js (1)
  • Parse (3-3)
spec/ReadPreferenceOption.spec.js (1)
  • Parse (3-3)

coderabbitai[bot]
coderabbitai bot previously approved these changes Aug 24, 2025
Added a type check in mongoFieldToParseSchemaField to ensure `type` is a string
before calling `startsWith`. This prevents crashes when Parse Server processes
MongoDB schema fields with undefined, null, or unexpected type values.

Closes parse-community#9847
@rgunindi rgunindi force-pushed the fix/type-validation-mongo-schema branch from 8d90d30 to 1f9b6fe Compare August 24, 2025 17:57
@rgunindi rgunindi changed the title fix(MongoSchemaCollection): prevent TypeError when type is not a string fix: Prevent TypeError when type is not a string Aug 24, 2025
Copy link
Member

@mtrezza mtrezza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test to demonstrate the issue. You experienced this in Parse Server 6, we also want to make sure this bug still exists in PS 8.

@mtrezza mtrezza changed the title fix: Prevent TypeError when type is not a string fix: Server crashes due to insufficient schema validation when type is not a string Aug 28, 2025
@mtrezza mtrezza changed the title fix: Server crashes due to insufficient schema validation when type is not a string fix: Server crashes due to insufficient schema validation when schema type is not a string Aug 28, 2025
@rgunindi
Copy link
Author

Please add a test to demonstrate the issue. You experienced this in Parse Server 6, we also want to make sure this bug still exists in PS 8.

@mtrezza
Thanks for the suggestion. I’ve added tests that demonstrate the issue and verified them against also current version ps8.

image

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
spec/MongoSchemaCollectionAdapter.spec.js (2)

3-3: Align Parse import with repo convention to ensure Parse.Error is available

Other specs import Parse via .Parse; this avoids ambiguity with the module export shape and is consistent across the repo.

-const Parse = require('parse/node');
+const Parse = require('parse/node').Parse;

101-131: Good coverage of valid type mappings

The table-driven checks for string/number/boolean/date/object/array/geo/file/bytes/polygon/pointer/relation look solid.

Optional: add role-based cases to catch regressions around special classes.

       const testCases = [
         { input: 'string', expected: { type: 'String' } },
@@
         { input: 'relation<_User>', expected: { type: 'Relation', targetClass: '_User' } },
         { input: 'relation<Post>', expected: { type: 'Relation', targetClass: 'Post' } },
+        { input: '*_Role', expected: { type: 'Pointer', targetClass: '_Role' } },
+        { input: 'relation<_Role>', expected: { type: 'Relation', targetClass: '_Role' } },
       ];
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1f9b6fe and f629526.

📒 Files selected for processing (1)
  • spec/MongoSchemaCollectionAdapter.spec.js (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-04-30T19:31:35.344Z
Learnt from: RahulLanjewar93
PR: parse-community/parse-server#9744
File: spec/ParseLiveQuery.spec.js:0-0
Timestamp: 2025-04-30T19:31:35.344Z
Learning: In the Parse Server codebase, the functions in QueryTools.js are typically tested through end-to-end behavior tests rather than direct unit tests, even though the functions are exported from the module.

Applied to files:

  • spec/MongoSchemaCollectionAdapter.spec.js
📚 Learning: 2025-05-04T20:41:05.147Z
Learnt from: mtrezza
PR: parse-community/parse-server#9445
File: spec/ParseLiveQuery.spec.js:1312-1338
Timestamp: 2025-05-04T20:41:05.147Z
Learning: New tests in the parse-server repository should use async/await with promise-based patterns rather than callback patterns with `done()`.

Applied to files:

  • spec/MongoSchemaCollectionAdapter.spec.js
📚 Learning: 2025-05-09T09:59:06.289Z
Learnt from: mtrezza
PR: parse-community/parse-server#9445
File: spec/ParseLiveQuery.spec.js:1340-1375
Timestamp: 2025-05-09T09:59:06.289Z
Learning: Tests in the parse-server repository should use promise-based approaches rather than callback patterns with `done()`. Use a pattern where a Promise is created that resolves when the event occurs, then await that promise.

Applied to files:

  • spec/MongoSchemaCollectionAdapter.spec.js
🧬 Code graph analysis (1)
spec/MongoSchemaCollectionAdapter.spec.js (2)
spec/schemas.spec.js (1)
  • Parse (3-3)
src/Controllers/SchemaController.js (1)
  • Parse (18-18)
🔇 Additional comments (1)
spec/MongoSchemaCollectionAdapter.spec.js (1)

155-189: The script is running; I’ll review the full implementation once available.

@rgunindi rgunindi force-pushed the fix/type-validation-mongo-schema branch from f629526 to 8710966 Compare August 28, 2025 18:34
coderabbitai[bot]
coderabbitai bot previously approved these changes Aug 28, 2025
@mtrezza
Copy link
Member

mtrezza commented Aug 28, 2025

Thanks, did you mean that you verified that the bug exists in PS8?

@rgunindi
Copy link
Author

Thanks, did you mean that you verified that the bug exists in PS8?

Yes, of course. This bug exists in Ps8.

…alidation and clear error message

- Add tests for valid field type conversions
- Add tests for invalid type handling (null, undefined, non-string values)
- Ensure Parse.Error code is thrown for invalid inputs
- Test coverage for the type validation improvements
- Add a clear error explanation
coderabbitai[bot]
coderabbitai bot previously approved these changes Aug 28, 2025
@rgunindi rgunindi requested a review from mtrezza August 28, 2025 22:26
Copy link

codecov bot commented Sep 10, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.01%. Comparing base (4b3f10b) to head (a882ffe).
⚠️ Report is 4 commits behind head on alpha.

Additional details and impacted files
@@           Coverage Diff           @@
##            alpha    #9848   +/-   ##
=======================================
  Coverage   93.01%   93.01%           
=======================================
  Files         187      187           
  Lines       15096    15098    +2     
  Branches      174      174           
=======================================
+ Hits        14041    14043    +2     
  Misses       1043     1043           
  Partials       12       12           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/Adapters/Storage/Mongo/MongoSchemaCollection.js (2)

25-47: Fail fast on unknown string types (optional but safer)

Right now unknown strings fall through and return undefined, which may propagate subtly. Consider throwing to surface bad data early. Backward-compat risk is low if such values are already invalid.

Apply:

     case 'polygon':
       return { type: 'Polygon' };
+    default:
+      throw new Parse.Error(
+        Parse.Error.INVALID_SCHEMA_OPERATION,
+        `Unsupported field type: '${type}' for field '${fieldName}' in class '${className}'.`
+      );

4-12: Apply: coerce invalid type to readable string and report class name

Search found only this occurrence of INVALID_SCHEMA_OPERATION in src; change is localized—apply the diff below.

-  if (!type || typeof type !== 'string') {
-    throw new Parse.Error(
-      Parse.Error.INVALID_SCHEMA_OPERATION,
-      `Invalid field type: ${type} for field '${fieldName}' in class '_SCHEMA' (id: ${className}). Expected a string. Fix the type mismatch in your schema configuration.`
-    );
-  }
+  if (!type || typeof type !== 'string') {
+    const received = typeof type === 'undefined' ? 'undefined' : String(type);
+    throw new Parse.Error(
+      Parse.Error.INVALID_SCHEMA_OPERATION,
+      `Invalid field type: ${received} for field '${fieldName}' in class '${className}'. Expected a string. Fix the type mismatch in your schema configuration.`
+    );
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a882ffe and 5852d3c.

📒 Files selected for processing (2)
  • spec/MongoSchemaCollectionAdapter.spec.js (1 hunks)
  • src/Adapters/Storage/Mongo/MongoSchemaCollection.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • spec/MongoSchemaCollectionAdapter.spec.js
🧰 Additional context used
🧬 Code graph analysis (1)
src/Adapters/Storage/Mongo/MongoSchemaCollection.js (6)
src/Adapters/Storage/Postgres/PostgresStorageAdapter.js (1)
  • fieldName (1434-1434)
src/RestWrite.js (2)
  • className (1742-1742)
  • schema (343-343)
src/Routers/SchemasRouter.js (3)
  • className (24-24)
  • className (86-86)
  • className (105-105)
src/GraphQL/loaders/parseClassMutations.js (1)
  • className (40-40)
src/GraphQL/loaders/parseClassTypes.js (1)
  • className (112-112)
src/GraphQL/loaders/parseClassQueries.js (1)
  • className (46-46)
🔇 Additional comments (1)
src/Adapters/Storage/Mongo/MongoSchemaCollection.js (1)

54-54: Good: caller now passes field and class for richer errors

Passing fieldName and schema._id addresses prior feedback and makes debugging much easier. LGTM.

… and class details

- Add fieldName and className parameters to mongoFieldToParseSchemaField function
- Update error message to include specific field name and class information
- Show collection name (_SCHEMA) and document ID for better debugging
- Pass field name and class ID from mongoSchemaFieldsToParseSchemaFields
- Enhanced error message format: 'Invalid field type: X for field Y in class _SCHEMA (id: Z)'
- Improves developer experience by providing clear context for schema validation errors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TypeError: type.startsWith is not a function when starting Parse Server with custom schema data
4 participants