# Typescript module error: "TypeError: matchInit value not a valid function"

**URL:** <https://forum.heroiclabs.com/t/typescript-module-error-typeerror-matchinit-value-not-a-valid-function/2616>\
**Category:** Runtime Framework\
**Tags:** getting-started, server-framework, typescript\
**Created:** [May 11, 2022, 1:08pm UTC](https://forum.heroiclabs.com/t/typescript-module-error-typeerror-matchinit-value-not-a-valid-function/2616 "2022-05-11T13:08:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Coxcopi](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/coxcopi/32/1145_2.png) [@Coxcopi](https://forum.heroiclabs.com/u/Coxcopi)\
**Post date:** [May 11, 2022, 1:08pm UTC](https://forum.heroiclabs.com/t/typescript-module-error-typeerror-matchinit-value-not-a-valid-function/2616/1 "2022-05-11T13:08:26Z")

</div>

Hey everyone! I’m really new to Nakama and tried to write a TypeScript module for an authoritative match. I don’t get any compilation errors when compiling with `npx tsc`, but when starting the nakama server using `docker-compose up`, I get the following error message:

```auto
nakama_1 | {"level":"error","ts":"2022-05-11T12:55:10.917Z","caller":"server/runtime_javascript.go:1521","msg":"Failed to eval JavaScript modules.","error":"TypeError: matchInit value not a valid function\n\tat github.com/heroiclabs/nakama/v3/server.(*RuntimeJavascriptInitModule).registerMatch.func1 (native)\n\tat InitModule (index.js:13:9(25))\n"}
nakama_1 | {"level":"error","ts":"2022-05-11T12:55:10.917Z","caller":"server/runtime.go:597","msg":"Error initialising JavaScript runtime provider","error":"TypeError: matchInit value not a valid function\n\tat github.com/heroiclabs/nakama/v3/server.(*RuntimeJavascriptInitModule).registerMatch.func1 (native)\n\tat InitModule (index.js:13:9(25))\n"}
nakama_1 | {"level":"fatal","ts":"2022-05-11T12:55:10.917Z","caller":"main.go:146","msg":"Failed initializing runtime modules","error":"TypeError: matchInit value not a valid function\n\tat github.com/heroiclabs/nakama/v3/server.(*RuntimeJavascriptInitModule).registerMatch.func1 (native)\n\tat InitModule (index.js:13:9(25))\n"}
nakama_nakama_1 exited with code 1

```

after which Nakama exits.

I’m using Nakama Server version `3.9.0` with docker-compose on `Ubuntu 20.04.4 LTS`.  
The version line in the docker-compose.yml looks like this:

```auto
nakama:
    image: heroiclabs/nakama:3.9.0

```

I would greatly appreciate any help, and if anyone knows what I might be doing wrong, please let me know 🙂

Below is my typescript code (before compiling):

```typescript
let InitModule : nkruntime.InitModule = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, initializer: nkruntime.Initializer) {
        logger.debug('Module initialized.');

        initializer.registerMatch('lobby', {
                matchInit,
                matchJoinAttempt,
                matchJoin,
                matchLoop,
                matchLeave,
                matchTerminate,
                matchSignal
        });
}

const matchInit = (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, params: {[key: string]: string}) : {state: nkruntime.MatchState, tickRate: number, label: string} => {
        logger.debug('Match initialized.');
        return {
                state: { },
                tickRate: 1,
                label: ''
        };
};

const matchJoinAttempt = (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, presences: nkruntime.Presence, metadata : {[key : string]: any}) : {state: nkruntime.MatchState, accept: boolean, rejectMessage?: string | undefined} | null => {
        return {
                state,
                accept: true
        };
};

const matchJoin = (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, presences: nkruntime.Presence[]) : {state: nkruntime.MatchState} | null => {
        return {state};
};

const matchLeave = (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, presences: nkruntime.Presence[]) : {state: nkruntime.MatchState} | null => {
        return {state};
};

const matchLoop = (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, messages: nkruntime.MatchMessage[]) : {state: nkruntime.MatchState} | null => {
        return {state};
};

const matchTerminate = (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, graceSeconds: number) : {state: nkruntime.MatchState} | null => {
        return {state};
};

const matchSignal = (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, data: string) : {state: nkruntime.MatchState, data?: string} | null => {
        logger.debug('Lobby match signal recieved: ' + data);
        return {state, data};
};

```

---

<div class="post-metadata">

**Author:** ![sesposito](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/sesposito/32/2594_2.png) [@sesposito](https://forum.heroiclabs.com/u/sesposito)\
**Post date:** [May 11, 2022, 3:11pm UTC](https://forum.heroiclabs.com/t/typescript-module-error-typeerror-matchinit-value-not-a-valid-function/2616/2 "2022-05-11T15:11:22Z")

</div>

Hello @Coxcopi, the Nakama JS runtime only supports ES5 JS at the moment, so anonymous arrow function declaration is unsupported, please use `const foo = function() {}` syntax to register the match handlers and it should resolve your issue.

Hope this helps.

---

<div class="post-metadata">

**Author:** ![Coxcopi](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/coxcopi/32/1145_2.png) [@Coxcopi](https://forum.heroiclabs.com/u/Coxcopi)\
**Post date:** [May 11, 2022, 4:08pm UTC](https://forum.heroiclabs.com/t/typescript-module-error-typeerror-matchinit-value-not-a-valid-function/2616/3 "2022-05-11T16:08:08Z")

</div>

Hey @sesposito, thanks, this seems to have fixed the error I was getting. However, I’m now getting another error:

```auto
nakama_1 | {"level":"error","ts":"2022-05-11T15:59:21.980Z","caller":"server/runtime_javascript.go:1521","msg":"Failed to eval JavaScript modules.","error":"GoError: failed to find InitModule function\n\tat github.com/heroiclabs/nakama/v3/server.(*RuntimeJavascriptInitModule).registerMatch.func1 (native)\n\tat InitModule (index.js:13:9(25))\n"}
nakama_1 | {"level":"error","ts":"2022-05-11T15:59:21.980Z","caller":"server/runtime.go:597","msg":"Error initialising JavaScript runtime provider","error":"GoError: failed to find InitModule function\n\tat github.com/heroiclabs/nakama/v3/server.(*RuntimeJavascriptInitModule).registerMatch.func1 (native)\n\tat InitModule (index.js:13:9(25))\n"}
nakama_1 | {"level":"fatal","ts":"2022-05-11T15:59:21.980Z","caller":"main.go:146","msg":"Failed initializing runtime modules","error":"GoError: failed to find InitModule function\n\tat github.com/heroiclabs/nakama/v3/server.(*RuntimeJavascriptInitModule).registerMatch.func1 (native)\n\tat InitModule (index.js:13:9(25))\n"}

```

This is how my InitModule and the rest of the script look like now:

```typescript
// Module init
let InitModule : nkruntime.InitModule = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, initializer: nkruntime.Initializer) {
        logger.debug('Module initialized.');
        // Reigster match
        initializer.registerMatch('lobby', {
                matchInit,
                matchJoinAttempt,
                matchJoin,
                matchLoop,
                matchLeave,
                matchTerminate,
                matchSignal
        });
};

// Match initialization function (runs once when the match is created either via rpc or through the matchmaker)
let matchInit: nkruntime.MatchInitFunction<nkruntime.MatchState> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, params: {[key: string]: string}) : {state: nkruntime.MatchState, tickRate: number, label: string} {
        logger.debug('Match initialized.');
        return {
                state: { },
                tickRate: 1,
                label: ''
        };
};

// When a player tries to join
const matchJoinAttempt: nkruntime.MatchJoinAttemptFunction<nkruntime.MatchState> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, presences: nkruntime.Presence, metadata : {[key : string]: any}) : {state: nkruntime.MatchState, ac> return {
                state,
                accept: true
        };
};

// When one (or multiple) player(s) actually join(s)
const matchJoin: nkruntime.MatchJoinFunction<nkruntime.MatchState> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, presences: nkruntime.Presence[]) : {state: nkruntime.MatchState} | null {
        return {state};
};

// When a player leaves
const matchLeave: nkruntime.MatchLeaveFunction<nkruntime.MatchState> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, presences: nkruntime.Presence[]) : {state: nkruntime.MatchState} | null {
        return {state};
};

// Runs every tick
const matchLoop: nkruntime.MatchLoopFunction<nkruntime.MatchState> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, messages: nkruntime.MatchMessage[]) : {state: nkruntime.MatchState} | null {
        return {state};
};

// Runs when the match gets terminated
const matchTerminate: nkruntime.MatchTerminateFunction<nkruntime.MatchState> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, graceSeconds: number) : {state: nkruntime.MatchState} | null {
        return {state};
};

const matchSignal: nkruntime.MatchSignalFunction<nkruntime.MatchState> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, dispatcher: nkruntime.MatchDispatcher, tick: number, state: nkruntime.MatchState, data: string) : {state: nkruntime.MatchState, data?: string} | null {
        logger.debug('Lobby match signal recieved: ' + data);
        return {state, data};
};

```

Thanks.

---

<div class="post-metadata">

**Author:** ![sesposito](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/sesposito/32/2594_2.png) [@sesposito](https://forum.heroiclabs.com/u/sesposito)\
**Post date:** [May 11, 2022, 5:05pm UTC](https://forum.heroiclabs.com/t/typescript-module-error-typeerror-matchinit-value-not-a-valid-function/2616/4 "2022-05-11T17:05:22Z")

</div>

The above script has syntax errors around the `matchJoinAttempt` function, these should be caught by the TypeScript compiler, after fixing them, I managed to successfully load the script on Nakama 3.11.0, so if after fixing them the issue persists, please upgrade to the latest version of the server.

---

<div class="post-metadata">

**Author:** ![Coxcopi](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/coxcopi/32/1145_2.png) [@Coxcopi](https://forum.heroiclabs.com/u/Coxcopi)\
**Post date:** [May 12, 2022, 6:37pm UTC](https://forum.heroiclabs.com/t/typescript-module-error-typeerror-matchinit-value-not-a-valid-function/2616/5 "2022-05-12T18:37:00Z")

</div>

Updating both the docker files and the npm dependencies fixed it, thank you so much!
