Methods already defined and collections already named in tests, some top-level code must be running twice

I have a project running Meteor 2.11 and when running the tests locally I get the following errors:

  • A method named '...' is already defined, and
  • There is already a collection named "...", if I comment out some code to try to avoid the first kind of error.

Each method and collection is defined in and exported from a dedicated file which is imported where relevant. It looks to me like something is making this code run twice for some reason. The tests seem to run fine on GitHub Actions and meteor run works just fine.

Anybody else experiencing the same issue?

I don’t think you need to import method file every time you use it.

I have encountered this particular issue on numerous occasions across various contexts. To effectively address this issue, I’ve employed a collection factory approach while also ensuring the singleton pattern for instance creation. This means that any collection is only instantiated once, and by doing this you won’t ever get this error.

To implement this you need to use a global context to keep track of the collections instantiated. For that I used globalThis, which provides a consistent global context based on the code’s execution environment. For instance, in browser environments, it corresponds to window , while in Node.js environments, it corresponds to global.

An example of factory of collections employing the Singleton pattern:

function createCollection(params) {
  globalThis.Collections = globalThis.Collections || {};
  globalThis.Collections[params.name] =
  globalThis.Collections[params.name] ||
    new Meteor.Collection(
     params.name,
     params.options
   );
  const collectionInstance = globalThis.Collections[params.name];
  return collectionInstance;
}

Revise all of your code to use the createCollection method for any instance of collection instantiation. The issue should be solved.

PD: globalThis is currently supported broadly, but if you encounter a problem in old browsers or node versions, refer to use a global-this or ungap/global-this polyfills.

I don’t think you need to import method file every time you use it.

I am not referring to methods by name, I am referring to them by reference, a bit like validated methods. And the issue still exist for collections since those are by reference with vanilla Meteor.

I’ll try that, should work. Still a bit shocked that there is no better solution. It seems to me like some sort of bundler (reify?) is serving this code through multiple routes which makes it execute twice or more, which is bad. No idea why it happens only in locally run tests.

Another option for collections seems to be to exploit the (non-public) option _suppressSameNameError: https://github.com/meteor/meteor/blob/527f0ffb6e050d7ed28721df31d1b1dcf2aa5ea7/packages/mongo/collection_tests.js#L27-L40

And instead of relying on globalThis for methods, I guess you can rely on Meteor.server.method_handlers on the server and Meteor.connection._methodHandlers on the client.

1 Like

I tried all of that and it seems to work for all the collections and methods that I define. Unfortunately, I use Meteor-Files which has some non-wrappable method definitions so I am at loss at how to resolve this. I think I am going to start to git bisect…

Not true.

Did not need too. Did some changes, updated some packages, updated my system, and now it works again. No idea of what was causing this :person_shrugging:. At least I learned how to manually handle duplicated methods and collection definitions.

OK. Actually the problem only went away because I did a worktree checkout of a branch that was created for the very purpose of fixing this issue. After having witnessed that it worked again, I merged that branch into the main branch. Guess what? When I go back to the main branch, run meteor npm ci, and try to run the tests I get the problem again. If I go to the worktree checked out branch no problem. Same code. Same installed dependencies. So something must be off inside Meteor’s local cache?! I’ll try purging it and see if that fixes it.

I tried rm -r node_modules .meteor/local && meteor npm ci without success… What options are left other than cloning the project fresh?

meteor reset also does not cut it, I am amazed. It also feels like building the app is unusually slow.

Weird. Tests should pass after the fix is merged into your main branch, same code, same deps.

Definitely, if the merge has been applied properly, and if the issue still hapenning, it is likely caused by some sort of cache. You tried to clean several cache layers and reinstall deps that may fix it.
But if after these, the issue persists, I would try to clean completely the ~/.meteor global directory. This folder contains various cached data related to Meteor projects for each version, build artifacts, package data, and test-related env cache. But this is like uninstalling Meteor completely. You would need to reinstall it again, and surely this process will take more time that you have already experienced.

It is really strange that you need to get into this last resort, but in my experience I have seen weird situacions solved actually by this.