Skip to content

fix(injectModel): fix pre-existing index rollback and required-field duplicate precheck#75

Open
Copilot wants to merge 2 commits intomainfrom
copilot/fix-pre-existing-index-rollback
Open

fix(injectModel): fix pre-existing index rollback and required-field duplicate precheck#75
Copilot wants to merge 2 commits intomainfrom
copilot/fix-pre-existing-index-rollback

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 2, 2026

Two edge-case bugs in createUniqueIndexes and getUniqueFieldFilter that could cause silent data loss and missed duplicate detection on live collections.

Changes

  • Rollback safety (createUniqueIndexes): Snapshot existing index names before the loop; only push indexes into createdIndexes if they weren't already present. The rollback path now exclusively drops indexes created by the current operation, preventing accidental destruction of pre-existing indexes when a later field fails.
const existingIndexNames = new Set((await Model.collection.indexes()).map(i => i.name));
// ...
const createdName = await Model.collection.createIndex({ [normalizedKey]: 1 }, indexOptions);
if (!existingIndexNames.has(createdName)) createdIndexes.push(createdName);
  • Required-field duplicate precheck (getUniqueFieldFilter): For required fields, return {} instead of { [fieldKey]: { $exists: true } }. MongoDB's unique index treats all missing-field documents as duplicate nulls, so the old filter could pass the precheck while createIndex still throws error 11000.
function getUniqueFieldFilter(fieldKey, isRequired) {
  if (isRequired) return {}; // include missing-field docs
  return { [fieldKey]: { $exists: true, $ne: null } };
}

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ur-backend-web-dashboard Ready Ready Preview, Comment Apr 2, 2026 8:23pm

…duplicate precheck

Agent-Logs-Url: https://github.com/yash-pouranik/urBackend/sessions/a4ebb02d-93e3-4686-9938-d19a6344dc1a

Co-authored-by: yash-pouranik <172860064+yash-pouranik@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix pre-existing index rollback and required-field duplicate precheck fix(injectModel): fix pre-existing index rollback and required-field duplicate precheck Apr 2, 2026
@yash-pouranik yash-pouranik marked this pull request as ready for review April 2, 2026 20:43
Copilot AI review requested due to automatic review settings April 2, 2026 20:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes two edge cases in the dynamic model injection utilities to prevent unsafe index rollback and improve duplicate detection before creating MongoDB unique indexes.

Changes:

  • Make unique-index rollback safe by tracking only indexes newly created during the current createUniqueIndexes run.
  • Adjust required-field duplicate precheck to include documents missing the field (aligning with MongoDB unique-index behavior for missing values).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


throw new Error(
`Cannot create unique index on '${normalizedKey}'. ${duplicates.length} duplicate values exist.${examples ? ` Examples: ${examples}` : ""}`,
const existingIndexes = await Model.collection.indexes();
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

Model.collection.indexes() will throw a NamespaceNotFound (code 26 / "ns not found") error when the collection doesn’t exist yet. createUniqueIndexes is called immediately after compiling a model for newly-created collections (before any inserts), so this can cause schema/collection creation to fail before any indexes are created. Consider wrapping the indexes() call in a try/catch and treating NamespaceNotFound as an empty index list (or ensuring the collection exists via Model.createCollection() / Model.init() before calling indexes()).

Suggested change
const existingIndexes = await Model.collection.indexes();
let existingIndexes = [];
try {
existingIndexes = await Model.collection.indexes();
} catch (err) {
const isNamespaceNotFound =
err &&
(err.code === 26 ||
err.codeName === "NamespaceNotFound" ||
err.message === "ns not found" ||
(typeof err.message === "string" &&
err.message.toLowerCase().includes("ns not found")));
if (!isNamespaceNotFound) {
throw err;
}
}

Copilot uses AI. Check for mistakes.
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.

fix(injectModel): fix pre-existing index rollback and required-field duplicate precheck

3 participants