Problem with EnvironmentVariable

In our applications, we have been using Meteor.EnvironmentVariable to handle cross-function calls. I find a discrepancy between how 2.14 and earlier work and 3.0. Here is a simple method that simulates the problem:

const linkContext = new Meteor.EnvironmentVariable();

Meteor.methods({
    async test() {
        console.log('Method invocation user', Meteor.userId());
        linkContext.withValue({ idd: Random.id() }, async () => {
            console.log('Link context', linkContext.get())
            console.log('Method invocation user inner', Meteor.userId());
        });
        return 'ok';
    }
})

In 2.14 I get as output

Method call user 5na9a9daGL3nf7KS8
Link context { idd: 'QERNEZZXqBvH2nH8X' }
Method call user inner 5na9a9daGL3nf7KS8

Whereas in 3.0 I get the error:

Method invocation user 5na9a9daGL3nf7KS8
Link context { idd: 'kwN57Kqi6uTEMGtLD' }
meteor://💻app/packages/accounts-base.js:762
 if (!currentInvocation) throw new Error("Meteor.userId can only be invoked in method calls or publications.");

Error: Meteor.userId can only be invoked in method calls or publications.
     at AccountsServer.userId (packages/accounts-base/accounts_server.js:124:13)
     at Object.Meteor.userId (packages/accounts-base/accounts_common.js:425:32)
     at server/main.js:32:64
     at EnvironmentVariableAsync.<anonymous> (packages/meteor.js:1241:23)
     at packages/meteor.js:740:19
     at AsyncLocalStorage.run (node:async_hooks:346:14)
     at Object.Meteor._runAsync (packages/meteor.js:737:37)
     at EnvironmentVariableAsync.withValue (packages/meteor.js:1236:19)
     at MethodInvocation.test (server/main.js:30:21)
     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1990:12)
     at packages/ddp-server/livedata_server.js:1899:11
     at EnvironmentVariableAsync.<anonymous> (packages/meteor.js:1241:23)
     at packages/meteor.js:740:19
     at AsyncLocalStorage.run (node:async_hooks:346:14)
     at Object.Meteor._runAsync (packages/meteor.js:737:37)
     at EnvironmentVariableAsync.withValue (packages/meteor.js:1236:19)

From a rough reconstruction, it seems that the local EnvironmentVariable overwrites the _CurrentMethodInvocation. Is there an alternative way to do this in the framework?

Can this be related to the loss of context described here: Can't we do Meteor.userAsync() in pubs anymore? - #3 by bratelefant ?!

1 Like

I’d definitely say yes, due to the fact that the I can confirm exact behavior with my own server function calls consuming Meteor.userId on the server from within publication and also this is what breaks meteor-collection-hooks for me on 3.0

It doesn’t seem related but I could be wrong. In my case it seems it is not possible to have multiple contexts at the same time.

Hello @denyhs, @grubba. Is there any confirmation or denial of the reported bug? Are any changes planned to make the EnvironmentVariable work the same in 3.0 as it did in 2.x?

Thank you very much.

Hi @pbeato, to confirm, are you testing this in beta-0?

I’ll try to reproduce this later to understand what’s happening.

Hi @denyhs, yes, I tried it in version 3.0-beta.0.

Hi all, same issue here with Meteor.userId on publications server side. Thanks for your work

Hi @denyhs is there any news about this? Thanks

I think this was fixed in the last Meteor 3.0 beta, right @denyhs?

Hi, we’ve released beta.4, which should be fixed now.

@pbeato, can you please test it again?