What userId to use for a Global storageRead from a TS RPC?

I am relatively new to Nakama and just got setup this week. I need to prove that I can read & write global data to all users. I successfully wrote a RPC that uses storageWrite and can see in the web console that the data object has the system userId (all the 0000…).

Note that the userId must be undefined.

const write: nkruntime.StorageWriteRequest = {
    collection: "UpdateCheck",
    key: "TCUpdateCheck",
    userId: undefined, //must be undefined to write as system user
    value: updatecheck,
    permissionRead: 2, // Only the server and owner can read
    permissionWrite: 0, // Only the server can write

I can make a request using the JS client with any user, with this code and it successfully returns the data. Note passing userId as an empty string.

const readStorage = async () => {
    try {
      const objects = await client.readStorageObjects(session, {
        object_ids: [
            collection: "UpdateCheck",
            key: "TCUpdateCheck",
            user_id: "",
      console.info("Read objects: %o", objects);
    } catch (error) {
      console.log("Error: %o", error.message);

However I need to make this same request as part of an RPC call, however in TypeScript I cannot find the right userId to get a correct response. According to the type userId is required and must be a string. The docs clearly say user is optional, so I don’t know what to pass to make the request.

Passing userId = “” or “null” or “undefined” returns error saying the userId was invalid
"TypeError: expects 'userId' value to be a valid id at github.com/heroiclabs/nakama/v3/server.(*runtimeJavascriptNakamaModule).storageRead.func1 (native)"

Pass the system ID in, no error but no data back either.

Heres my read RPC

function rpcVersionCheck(
  ctx: nkruntime.Context,
  logger: nkruntime.Logger,
  nk: nkruntime.Nakama,
  payload: string
): string {
  if (!ctx.userId) {
    throw Error("No user ID in context");
  if (!payload) {
    throw Error("Expects payload.");

  let request = {} as any;
  try {
    request = JSON.parse(payload);
  } catch (error) {
    logger.error("Error parsing json message: %q", error);
    throw error;

  const userId = "00000000-0000-0000-0000-000000000000";
  let objectIds: nkruntime.StorageReadRequest[] = [
    { key: "UpdateCheck", collection: "TCUpdateCheck", userId: "" },

  let results: nkruntime.StorageObject[] = [];

  try {
    results = nk.storageRead(objectIds);
  } catch (error) {
    logger.error("Failed to read storage object %s", error);

  logger.info("installedVersion", request.installedVersion);
  logger.info("UpdateCheckREAD", JSON.stringify(results));
  return JSON.stringify(results);
  1. Versions: Nakama 3.12.0+f5e935d6, {Docker on Ubuntu}, {client library (JS “@heroiclabs/nakama-js”: “^2.4.1”,)}
  2. Server Framework Runtime language (If relevant) TS/JS

Any advice would be very welcome as I am really hopeful Nakama is our saviour on this project but if I can’t make global data calls I am can’t proceed.

Thanks so much

Oh No!!! (but also OH YES!!!)
Seconds after posting I was editing the post and saw I had my key and collection values switched round on the RPC read. It now works

Major face palm

Glad we could rubber duck for you @toby