nextauthjs/next-auth · error · TypeError
Missing Loops API Key or TransactionalId
Error message
Missing Loops API Key or TransactionalId
What it means
The Loops provider throws a TypeError in sendVerificationRequest when either provider.apiKey or provider.transactionalId is falsy. Both are mandatory to call Loops' transactional email API, so the provider validates them up front before making any network request. This is a configuration error, not a runtime/network failure.
Source
Thrown at packages/core/src/providers/loops.ts:57
* })
* ```
*
* @typedef LoopsUserConfig
*/
export default function Loops(config: LoopsUserConfig): LoopsConfig {
return {
id: "loops",
apiKey: "",
type: "email",
name: "Loops",
from: "Auth.js <no-reply@authjs.dev>",
maxAge: 24 * 60 * 60,
transactionalId: config.transactionalId || "",
async sendVerificationRequest(params: Params) {
const { identifier: to, provider, url } = params
if (!provider.apiKey || !provider.transactionalId)
throw new TypeError("Missing Loops API Key or TransactionalId")
const res = await fetch("https://app.loops.so/api/v1/transactional", {
method: "POST",
headers: {
Authorization: `Bearer ${provider.apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
transactionalId: provider.transactionalId,
email: to,
dataVariables: {
url: url,
},
}),
})
if (!res.ok) {
throw new Error("Loops Send Error: " + JSON.stringify(await res.json()))
}View on GitHub (pinned to a1a16a5a77)
Solutions
- Set the API key: pass apiKey: process.env.LOOPS_API_KEY and ensure the env var exists where the app runs
- Create a transactional email in Loops (with a {{url}} data variable) and pass its transactionalId to the provider
- Double-check provider option key names (apiKey, transactionalId) match the provider's expected shape
- Add a startup assertion/log that both fields are present before accepting traffic
Example fix
// before
Loops({ transactionalId: config.transactionalId || "" }) // empty string -> throw
// after
Loops({
apiKey: process.env.LOOPS_API_KEY,
transactionalId: process.env.LOOPS_TRANSACTIONAL_ID, // set in env
}) Defensive patterns
Strategy: validation
Validate before calling
if (!process.env.LOOPS_API_KEY) throw new Error('LOOPS_API_KEY is required')
if (!process.env.LOOPS_TRANSACTIONAL_ID) throw new Error('LOOPS_TRANSACTIONAL_ID is required') Type guard
function isLoopsConfig(c: { apiKey?: string; transactionalId?: string }): c is { apiKey: string; transactionalId: string } {
return typeof c.apiKey === 'string' && c.apiKey.length > 0 && typeof c.transactionalId === 'string' && c.transactionalId.length > 0
} Try / catch
try {
await sendVerificationRequest(params)
} catch (e) {
if (e instanceof TypeError && e.message.includes('Missing Loops API Key')) {
console.error('Loops provider misconfigured: set apiKey and transactionalId')
}
} Prevention
- Create the transactional email in Loops first, then wire its transactionalId into config
- Set LOOPS_API_KEY and the transactionalId in every deployment environment
- Assert required provider options at app startup, before accepting sign-in traffic
- Copy option key names exactly: apiKey, transactionalId
When it happens
Trigger: Calling the Loops email provider's sendVerificationRequest with a config missing apiKey (e.g. process.env.LOOPS_API_KEY unset) or transactionalId (not passed and not defaulted) — the guard `if (!provider.apiKey || !provider.transactionalId)` fires immediately.
Common situations: Forgetting to set LOOPS_API_KEY in the deployment environment; creating the provider without a transactionalId because the developer hasn't created the transactional email template in Loops yet; typos in config keys so the fields land undefined.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Missing Postmark API Key
- Loops Send Error: ${JSON.stringify(await res.json())}
- malformed Mailgun domain
- Hasura client error: Please provide an adminSecret
- Hasura client error: Please provide a graphql endpoint
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/0fb6e04df58234ac.
Report an issue: GitHub.