"Meteor code must always run within a Fiber" when calling Collection.insert on server "Meteor code must always run within a Fiber" when calling Collection.insert on server javascript javascript

"Meteor code must always run within a Fiber" when calling Collection.insert on server


Just wrapping your function in a Fiber might not be enough and can lead to unexpected behavior.

The reason is, along with Fiber, Meteor requires a set of variables attached to a fiber. Meteor uses data attached to a fiber as a dynamic scope and the easiest way to use it with 3rd party api is to use Meteor.bindEnvironment.

T.post('someurl', Meteor.bindEnvironment(function (err, res) {  // do stuff  // can access Meteor.userId  // still have MongoDB write fence}, function () { console.log('Failed to bind environment'); }));

Watch these videos on evented mind if you want to know more: https://www.eventedmind.com/posts/meteor-dynamic-scoping-with-environment-variableshttps://www.eventedmind.com/posts/meteor-what-is-meteor-bindenvironment


As mentioned above it is because your executing code within a callback.

Any code you're running on the server-side needs to be contained within a Fiber.

Try changing your getServices function to look like this:

function getServices(services) {  Fiber(function() {     services = [];    request('http://some-server/vshell/index.php?type=services&mode=json', function (error, response, body) {      var resJSON = JSON.parse(body);       _.each(resJSON, function(data) {         var host = data["host_name"];         var service = data["service_description"];         var hardState = data["last_hard_state"];         var currState = data["current_state"];         services+={host: host, service: service, hardState: hardState, currState: currState};         Services.insert({host: host, service: service, hardState: hardState, currState: currState});      });    });  }).run();  }

I just ran into a similar problem and this worked for me. What I have to say though is that I am very new to this and I do not know if this is how this should be done.

You probably could get away with only wrapping your insert statement in the Fiber, but I am not positive.


Based on my tests you have to wrap the insert in code I tested that is similar to the above example.

For example, I did this and it still failed with Fibers error.

function insertPost(args) {  if(args) {Fiber(function() {     post_text = args.text.slice(0,140);    T.post('statuses/update', { status: post_text },         function(err, reply) {                      if(reply){                // TODO remove console output                console.log('reply: ' + JSON.stringify(reply,0,4));                console.log('incoming twitter string: ' + reply.id_str);                // TODO insert record                var ts = Date.now();                id = Posts.insert({                    post: post_text,                     twitter_id_str: reply.id_str,                    created: ts                });            }else {                console.log('error: ' + JSON.stringify(err,0,4));                // TODO maybe store locally even though it failed on twitter                // and run service in background to push them later?            }        }    );}).run();  }}

I did this and it ran fine with no errors.

function insertPost(args) {  if(args) { post_text = args.text.slice(0,140);T.post('statuses/update', { status: post_text },     function(err, reply) {                  if(reply){            // TODO remove console output            console.log('reply: ' + JSON.stringify(reply,0,4));            console.log('incoming twitter string: ' + reply.id_str);            // TODO insert record            var ts = Date.now();            Fiber(function() {                id = Posts.insert({                    post: post_text,                     twitter_id_str: reply.id_str,                    created: ts                });            }).run();        }else {            console.log('error: ' + JSON.stringify(err,0,4));            // TODO maybe store locally even though it failed on twitter            // and run service in background to push them later?        }    });  }}

I thought this might help others encountering this issue. I have not yet tested calling the asynchy type of external service after internal code and wrapping that in a Fiber. That might be worth testing as well. In my case I needed to know the remote action happened before I do my local action.

Hope this contributes to this question thread.