Skip to content

fix: A null Date field is returned as epoch (1970) instead of null#10547

Open
dblythy wants to merge 1 commit into
parse-community:alphafrom
dblythy:fix/null-date-mongo
Open

fix: A null Date field is returned as epoch (1970) instead of null#10547
dblythy wants to merge 1 commit into
parse-community:alphafrom
dblythy:fix/null-date-mongo

Conversation

@dblythy

@dblythy dblythy commented Jul 5, 2026

Copy link
Copy Markdown
Member

Closes #7576

Summary by CodeRabbit

  • Bug Fixes
    • Fixed Mongo-to-Parse conversion so cleared expiresAt and lastUsed values stay null instead of being turned into a date value.
    • Ensured existing date values continue to be converted correctly.
  • Tests
    • Added coverage for null handling on expiresAt and lastUsed to prevent regressions.

@parse-github-assistant

Copy link
Copy Markdown

🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review.

Tip

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

Note

Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect.

Caution

Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Modified mongoObjectToParseObject in MongoTransform.js so that expiresAt and lastUsed fields preserve a null value instead of being coerced into an epoch Date. Added two unit tests validating this null-preservation behavior for both fields.

Changes

Null Date Field Fix

Layer / File(s) Summary
Preserve null for Date fields
src/Adapters/Storage/Mongo/MongoTransform.js
expiresAt and lastUsed now return null directly when the stored Mongo value is null, instead of passing it through new Date(null); non-null values are still encoded via Parse._encode(new Date(...)).
Tests for null handling
spec/MongoTransform.spec.js
Added tests verifying mongoObjectToParseObject returns null for expiresAt and lastUsed when the Mongo value is null and the field type is Date.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Related issues: #7576 — Fixes Parse Server returning an epoch Date (1970-01-01) instead of null for Date fields set to null in MongoDB.

Suggested labels: bug, mongodb

Suggested reviewers: dblythy, mtrezza


🐛 A date once null, now stays null and true,
No more 1970 haunting the query view.
Two little tests to guard the fix in place,
Null stays null—a bug erased without a trace.

🚥 Pre-merge checks | ✅ 5 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description only closes the issue and omits the required Issue, Approach, and Tasks sections. Expand the template with a brief issue summary, the implementation approach, and completed task checkboxes.
Engage In Review Feedback ❓ Inconclusive No review-thread or discussion metadata is available; the diff only shows the null-date fix and tests, so feedback engagement can’t be verified. Provide PR review comments/threads or approval history showing feedback was discussed and either implemented in a commit or retracted.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the required fix: prefix and matches the null date bug being addressed.
Linked Issues check ✅ Passed The code and tests address issue #7576 by preserving null for the affected Mongo date fields.
Out of Scope Changes check ✅ Passed The changes are limited to the null-date fix and its tests, with no unrelated scope added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Security Check ✅ Passed Only null-preservation for date fields was added; no new injection, auth-bypass, or sensitive-data exposure patterns appear in the diff.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
spec/MongoTransform.spec.js (1)

432-445: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Missing regression coverage for the non-null Date case.

Both new tests only exercise null input. Adding a companion assertion for a non-null expiresAt/lastUsed value would guard against the format regression flagged in MongoTransform.js (e.g., asserting output.expiresAt.__type === 'Date' and the expected .iso value), since the null-check refactor also touched the non-null branch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@spec/MongoTransform.spec.js` around lines 432 - 445, Add regression coverage
in the existing MongoTransform spec for the non-null Date path alongside the new
null cases. In the same test area that calls transform.mongoObjectToParseObject
for expiresAt and lastUsed, include assertions for a real Date value so the
non-null branch in MongoTransform.js is verified too, checking the returned
Parse Date shape and expected ISO string through output.expiresAt and
output.lastUsed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@spec/MongoTransform.spec.js`:
- Around line 432-445: Add regression coverage in the existing MongoTransform
spec for the non-null Date path alongside the new null cases. In the same test
area that calls transform.mongoObjectToParseObject for expiresAt and lastUsed,
include assertions for a real Date value so the non-null branch in
MongoTransform.js is verified too, checking the returned Parse Date shape and
expected ISO string through output.expiresAt and output.lastUsed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cf25b688-3900-4089-8171-6d0a4bb08f3e

📥 Commits

Reviewing files that changed from the base of the PR and between 7e9d53a and d497ce5.

📒 Files selected for processing (2)
  • spec/MongoTransform.spec.js
  • src/Adapters/Storage/Mongo/MongoTransform.js

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.66%. Comparing base (cce91e5) to head (d497ce5).
⚠️ Report is 1 commits behind head on alpha.

Additional details and impacted files
@@           Coverage Diff           @@
##            alpha   #10547   +/-   ##
=======================================
  Coverage   92.66%   92.66%           
=======================================
  Files         193      193           
  Lines       16981    16981           
  Branches      248      248           
=======================================
  Hits        15736    15736           
  Misses       1224     1224           
  Partials       21       21           

☔ View full report in Codecov by Harness.
📢 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.

@dblythy dblythy requested a review from a team July 5, 2026 02:48
@Moumouls

Moumouls commented Jul 6, 2026

Copy link
Copy Markdown
Member

@coderabbitai does a fix need to be applied elsewhere in the code to patch Date on standard objects or fields ? It seems the fix is scoped on a specific field

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
fd MongoTransform.js
echo "---outline---"
ast-grep outline src/Adapters/Storage/Mongo/MongoTransform.js --items all | head -100
echo "---mongoObjectToParseObject---"
rg -n "mongoObjectToParseObject" -A 100 src/Adapters/Storage/Mongo/MongoTransform.js | head -200

Length of output: 6513


🏁 Script executed:

#!/bin/bash
sed -n '1213,1280' src/Adapters/Storage/Mongo/MongoTransform.js

Length of output: 430


🏁 Script executed:

#!/bin/bash
awk 'NR>=1213 && NR<=1290' src/Adapters/Storage/Mongo/MongoTransform.js

Length of output: 2987


🏁 Script executed:

#!/bin/bash
awk 'NR>=1034 && NR<=1105' src/Adapters/Storage/Mongo/MongoTransform.js
echo "---valueAsDate---"
awk 'NR>=218 && NR<=230' src/Adapters/Storage/Mongo/MongoTransform.js

Length of output: 2634


@Moumouls Good question — I checked this carefully.

Custom/user-defined Date fields are already safe. Any field not explicitly special-cased in mongoObjectToParseObject falls through to the default branch, which calls nestedMongoObjectToNestedParseObject(mongoObject[key]). That function has an early guard:

case 'object':
  if (mongoObject === null) {
    return null;
  }

So a null-valued custom Date field never reaches new Date(...) and is already returned correctly as null — no fix needed there.

However, the same bug pattern still exists for two other hardcoded fields in mongoObjectToParseObject that this PR didn't touch:

case 'updatedAt':
case '_updated_at':
  restObject['updatedAt'] = Parse._encode(new Date(mongoObject[key])).iso;
  break;
case 'createdAt':
case '_created_at':
  restObject['createdAt'] = Parse._encode(new Date(mongoObject[key])).iso;
  break;

These call new Date(mongoObject[key]) unconditionally, exactly like the pre-fix expiresAt/lastUsed code did. In normal operation Parse Server always sets createdAt/updatedAt itself, so they're never null in practice — but if a document were ever manually edited/corrupted directly in MongoDB (or migrated from another system) with a null value there, you'd hit the identical 1970-01-01 bug.

So to summarize:

  • No fix needed for arbitrary/custom schema Date fields — already handled correctly.
  • The fix is intentionally scoped to expiresAt/lastUsed because those are what issue #7576 reported, but for full defensive consistency the same mongoObject[key] === null ? null : ... guard could also be applied to createdAt/updatedAt for symmetry, even though it's a much lower-risk edge case.

Would you like me to open a follow-up issue for applying the same null-guard to createdAt/updatedAt?

@Moumouls

Moumouls commented Jul 6, 2026

Copy link
Copy Markdown
Member

@dblythy maybe be createdAt and updatedAt should be also patched ?

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.

When a date is set to null in mongoDB, parse server returns a Date set at 1970-01-01

2 participants