fix(translation): prevent duplicate locale error on server restart (#14345)

The translation module's defaults loader throws a warning on every server
restart after the first run because the upsert method uses `id` as the
unique key, but defaultLocales only contains `code` and `name`.

This causes the upsert to always attempt creation, which fails on the
unique `code` constraint with: "Locale with code: en-US, already exists."

Fix: Fetch existing locales first and map their IDs into defaultLocales
so upsert can properly identify existing records and update them.
This commit is contained in:
0xFl4g
2025-12-18 10:56:18 +00:00
committed by GitHub
parent 92d240d749
commit 0277062fec
2 changed files with 27 additions and 2 deletions

View File

@@ -3,7 +3,10 @@ import {
Logger,
ModulesSdkTypes,
} from "@medusajs/framework/types"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
import {
ContainerRegistrationKeys,
normalizeLocale,
} from "@medusajs/framework/utils"
import Locale from "@models/locale"
/**
@@ -70,7 +73,24 @@ export default async ({ container }: LoaderOptions): Promise<void> => {
container.resolve("localeService")
try {
const resp = await localeService_.upsert(defaultLocales)
// Fetch existing locales to map their IDs for upsert
// The upsert method uses `id` as the key, so we need to include IDs for existing locales
const existingLocales = await localeService_.list(
{},
{ select: ["id", "code"] }
)
const existingByCode = new Map(
existingLocales.map((l) => [l.code, l.id])
)
// Map default locales to include IDs for existing ones
const localesToUpsert = defaultLocales.map((locale) => {
const normalizedCode = normalizeLocale(locale.code)
const existingId = existingByCode.get(normalizedCode)
return existingId ? { ...locale, id: existingId } : locale
})
const resp = await localeService_.upsert(localesToUpsert)
logger.debug(`Loaded ${resp.length} locales`)
} catch (error) {
logger.warn(