cube-js/cube · error

e.toString()

Error message

e.toString()

What it means

In the API Gateway auth error path (packages/cubejs-api-gateway/src/gateway.ts:2868), when token authorization throws an unexpected error, the handler logs 'Auth Error' and responds 500 with { error: e.toString(), stack }. The thrown value's stringification is surfaced verbatim to the client, which usually indicates a non-Error throw or a misconfigured JWT secret/checker rather than a normal 401 auth rejection.

Source

Thrown at packages/cubejs-api-gateway/src/gateway.ts:2868

        const error = e.originalError || e;
        const stack = getEnv('devMode') ? error.stack : undefined;
        this.log({
          type: error.message,
          url: req.url,
          token,
          error: stack || error.toString()
        }, <any>req);

        res.status(e.status).json({ error: e.message });
      } else if (e instanceof Error) {
        const stack = getEnv('devMode') ? e.stack : undefined;
        this.log({
          type: 'Auth Error',
          token,
          error: stack || e.toString()
        }, <any>req);

        res.status(500).json({
          error: e.toString(),
          stack,
        });
      }
    }
  }

  protected checkAuth: RequestHandler = async (req, res, next) => {
    await this.checkAuthWrapper(this.checkAuthFn, req, res, next);
  };

  protected checkAuthSystemMiddleware: RequestHandler = async (req, res, next) => {
    await this.checkAuthWrapper(this.checkAuthSystemFn, req, res, next);
  };

  protected requestContextMiddleware: RequestHandler = async (req: Request, res: ExpressResponse, next: NextFunction) => {
    try {
      req.context = await this.contextByReq(req, req.securityContext, getRequestIdFromRequest(req));

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Check the returned `error`/`stack` in the 500 body to identify the underlying exception
  2. Verify the client's JWT is signed with the same secret as CUBEJS_API_SECRET and uses a supported algorithm
  3. Make any custom checkAuth/securityContext functions throw standard Errors and return 401 for auth failures instead of letting exceptions escape
  4. Regenerate/reissue tokens if the secret was rotated

Example fix

// before (custom auth that throws)
checkAuth: (req, auth) => { if (!auth) throw new Error('no auth'); }
// after
checkAuth: async (req, auth) => { if (!auth) throw new AuthenticationError('no auth'); }
Defensive patterns

Strategy: try-catch

Validate before calling

function isWellFormedJwt(token) {
  return typeof token === 'string' && token.split('.').length === 3;
}

Type guard

function isAuthError(e: unknown): e is Error {
  return e instanceof Error && 'name' in e;
}

Try / catch

// client-side
try {
  const res = await cubejsApi.load(query);
} catch (e) {
  if (e?.response?.status === 500 && e.response.data?.error) {
    console.error('Auth path threw:', e.response.data.error, e.response.data.stack);
  }
}

Prevention

When it happens

Trigger: A request with an auth token where the token check throws — e.g. jwt.verify failing with a non-standard error, a custom checkAuth function throwing, or a wrong/malformed CUBEJS_API_SECRET causing an exception in the auth path.

Common situations: Mismatched JWT signing secret between client and Cube; expired/malformed tokens handled by custom auth code that throws; auth functions written async but consumed synchronously, causing unhandled rejections surfacing here.

Related errors


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