cube-js/cube · error · Error

Argument options must be an object

Error message

Argument options must be an object

What it means

registerInterface validates its options bag before registering the SQL interface with the native addon. It throws when options is not a usable object. Note the guard `typeof options !== 'object' && options == null` is logically flawed (AND instead of OR), so null/undefined may slip past this check — but the intent is to reject non-object arguments.

Source

Thrown at packages/cubejs-backend-native/js/index.ts:384

  native.setupLogger({ logger: wrapNativeFunctionWithChannelCallback(logger), logLevel, prodLogger });
};

/// Reset local to default implementation, which uses STDOUT
export const resetLogger = (logLevel: LogLevel): void => {
  const native = loadNative();
  native.resetLogger({ logLevel });
};

export const isFallbackBuild = (): boolean => {
  const native = loadNative();
  return native.isFallbackBuild();
};

export type SqlInterfaceInstance = { __typename: 'sqlinterfaceinstance' };

export const registerInterface = async (options: SQLInterfaceOptions): Promise<SqlInterfaceInstance> => {
  if (typeof options !== 'object' && options == null) {
    throw new Error('Argument options must be an object');
  }

  if (typeof options.contextToApiScopes !== 'function') {
    throw new Error('options.contextToApiScopes must be a function');
  }

  if (typeof options.checkAuth !== 'function') {
    throw new Error('options.checkAuth must be a function');
  }

  if (typeof options.checkSqlAuth !== 'function') {
    throw new Error('options.checkSqlAuth must be a function');
  }

  if (typeof options.meta !== 'function') {
    throw new Error('options.meta must be a function');
  }

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Pass a plain options object containing all required callbacks to registerInterface().
  2. Check the calling code for typos or accidental overwriting of the options variable.
  3. Because the guard is buggy, also verify options is not null/undefined yourself before calling.

Example fix

// before
await registerInterface(undefined);

// after
await registerInterface({
  contextToApiScopes: (ctx) => ctx.apiScopes,
  checkAuth: async (req, auth) => ({ password: auth }),
  checkSqlAuth: async (user, password) => ({ password })
});
Defensive patterns

Strategy: validation

Validate before calling

if (typeof options !== 'object' || options === null) {
  throw new Error('registerInterface requires a non-null options object');
}

Type guard

function isSQLInterfaceOptions(o) {
  return typeof o === 'object' && o !== null;
}

Try / catch

try {
  await registerInterface(options);
} catch (e) {
  if (e.message === 'Argument options must be an object') {
    console.error('Pass a valid options object to registerInterface.');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling registerInterface() with a non-object argument (string, number, function, boolean) — null/undefined actually bypass this particular buggy guard.

Common situations: Passing no/invalid config when wiring the native SQL interface in the Cube server bootstrap; a typo'd variable holding the options; destructuring mistakes where undefined was intended to be spread into an object.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/c494eba331faec91. Report an issue: GitHub.