Skip to content

TRANSFORM_ERROR When trying to generate mikro-orm schema. #28

@normalid-awa

Description

@normalid-awa

While trying to use npx @better-auth/cli generate --config ./src/auth/auth.server.ts the error below showns up

>npm run auth:generate

> ipsc-scoreboard-tanstack@1.0.0 auth:generate
> npx @better-auth/cli generate --config ./src/auth/auth.server.ts

2025-08-19T09:25:04.272Z ERROR [Better Auth]: Couldn't read your auth config. [Error: TRANSFORM_ERROR: G:\: Definitely assigned fields cannot be initialized here, but only in the constructor

tsconfig

{
	"compilerOptions": {
		"jsx": "react-jsx",
		"moduleResolution": "Bundler",
		"module": "ESNext",
		"target": "es2023",
		"skipLibCheck": true,
		"strictNullChecks": true,
		"verbatimModuleSyntax": false,
		"declaration": true,
		"emitDecoratorMetadata": true,
		"experimentalDecorators": true,
		"esModuleInterop": true,
		"paths": {
			"@/*": ["./src/*"]
		}
	}
}

package.json

{
	"name": "ipsc-scoreboard-tanstack",
	"version": "1.0.0",
	"description": "",
	"main": "index.js",
	"type": "module",
	"scripts": {
		"auth:generate": "npx @better-auth/cli generate --config ./src/auth/auth.server.ts",
		"auth:migrate": "npx @better-auth/cli migrate --config ./src/auth/auth.server.ts",
		"dev": "vite dev",
		"build": "vite build"
	},
	"keywords": [],
	"author": "",
	"license": "ISC",
	"dependencies": {
		"@daveyplate/better-auth-tanstack": "^1.3.6",
		"@emotion/react": "^11.14.0",
		"@emotion/styled": "^11.14.1",
		"@fontsource/roboto": "^5.2.6",
		"@mikro-orm/core": "^6.4.16",
		"@mikro-orm/migrations": "^6.4.16",
		"@mikro-orm/postgresql": "^6.4.16",
		"@mikro-orm/reflection": "^6.4.16",
		"@mui/icons-material": "^7.2.0",
		"@mui/material": "^7.2.0",
		"@tanstack/react-query": "^5.83.0",
		"@tanstack/react-router": "^1.127.8",
		"@tanstack/react-router-devtools": "^1.127.9",
		"@tanstack/react-start": "^1.127.8",
		"@vitejs/plugin-react-swc": "^4.0.1",
		"better-auth": "^1.3.1",
		"better-auth-mikro-orm": "^0.4.3",
		"material-ui-confirm": "^4.0.0",
		"nodemailer": "^7.0.5",
		"pg": "^8.16.3",
		"react": "^19.1.0",
		"react-dom": "^19.1.0",
		"vite": "^7.0.4"
	},
	"devDependencies": {
		"@mikro-orm/cli": "^6.4.16",
		"@types/pg": "^8.15.4",
		"@types/react": "^19.1.8",
		"@types/react-dom": "^19.1.6",
		"@types/web-bluetooth": "^0.0.21",
		"@vitejs/plugin-basic-ssl": "^2.1.0",
		"ts-node": "^10.9.2",
		"typescript": "^5.8.3",
		"vite-tsconfig-paths": "^5.1.4"
	}
}

mikro-orm.config.ts

import { Options, PostgreSqlDriver } from "@mikro-orm/postgresql";
import { TsMorphMetadataProvider } from "@mikro-orm/reflection";
import { Migrator } from "@mikro-orm/migrations";
import { DB_URL } from "./config";
import { ShooterProfile } from "./db/schema/shooterProfile";

const config: Options = {
	driver: PostgreSqlDriver,
	clientUrl: DB_URL,
	entities: [ShooterProfile],
	migrations: {
		path: "src/db/migrations",
	},
	metadataProvider: TsMorphMetadataProvider,
	debug: true,
	extensions: [Migrator],
};

export default config;

db.ts

import config from "@/mikro-orm.config";
import { MikroORM } from "@mikro-orm/postgresql";

const orm = await MikroORM.init(config);
export default orm;

auth.config.ts

import { betterAuth } from "better-auth";
import { reactStartCookies } from "better-auth/react-start";
import {
	emailOTP,
	multiSession,
	username,
	organization,
} from "better-auth/plugins";
import nodemailer from "nodemailer";
import { mikroOrmAdapter } from "better-auth-mikro-orm";
import orm from "@/db/db";

let emailVerificationHtmlTemplate: string;
let passwordResetVerificationCodeHtmlTemplate: string;

const transporter = nodemailer.createTransport({
	host: process.env.SMTP_HOST as string,
	port: parseInt(process.env.SMTP_PORT as string),
	secure: false, // true for 465, false for other ports
	auth: {
		user: process.env.SMTP_USER as string,
		pass: process.env.SMTP_PASSWORD as string,
	},
});

export const auth = betterAuth({
	database: mikroOrmAdapter(orm),
	advanced: {
		ipAddress: {
			ipAddressHeaders: ["x-client-ip", "x-forwarded-for"],
			disableIpTracking: false,
		},
	},
	emailAndPassword: {
		enabled: true,
		requireEmailVerification: true,
		revokeSessionsOnPasswordReset: true,
	},
	emailVerification: {
		sendOnSignUp: true,
		autoSignInAfterVerification: true,
		sendVerificationEmail: async ({ user, url, token }, request) => {
			if (!emailVerificationHtmlTemplate)
				emailVerificationHtmlTemplate = (
					await import(`@/email/template/verificationEmailTemplate.html?raw`)
				).default;

			const info = await transporter.sendMail({
				from: process.env.SMTP_EMAIL_VERIFY_FROM as string,
				to: user.email,
				subject: "Verify your email address",
				text: `Click the link to verify your email: ${url}`,
				html: emailVerificationHtmlTemplate.replace(
					"{{verificationLink}}",
					url,
				),
			});
			console.log(info);
		},
	},
	socialProviders: {
		github: {
			clientId: process.env.AUTH_GITHUB_ID as string,
			clientSecret: process.env.AUTH_GITHUB_SECRET as string,
		},
		google: {
			clientId: process.env.AUTH_GOOGLE_ID as string,
			clientSecret: process.env.AUTH_GOOGLE_SECRET as string,
		},
		microsoft: {
			clientId: process.env.AUTH_MICROSOFT_ENTRA_ID_ID as string,
			clientSecret: process.env.AUTH_MICROSOFT_ENTRA_ID_SECRET as string,
			tenantId: process.env.AUTH_MICROSOFT_ENTRA_ID_ISSUER as string,
		},
	},
	plugins: [
		reactStartCookies(),
		username(),
		emailOTP({
			expiresIn: 5 * 60,
			async sendVerificationOTP({ email, otp, type }) {
				if (!emailVerificationHtmlTemplate)
					passwordResetVerificationCodeHtmlTemplate = (
						await import(
							`@/email/template/passwordResetVerificationCode.html?raw`
						)
					).default;

				let subject = "";
				let html = ";";

				switch (type) {
					case "forget-password":
						subject = "Password reset verification code";
						html = passwordResetVerificationCodeHtmlTemplate.replace(
							"{{otp}}",
							otp,
						);
						break;
				}

				const info = await transporter.sendMail({
					from: process.env.SMTP_EMAIL_VERIFY_FROM as string,
					to: email,
					subject: subject,
					text: subject,
					html: html,
				});
				console.log(info);
			},
		}),
		multiSession(),
		organization({
			allowUserToCreateOrganization: true,
		}),
	],
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions