Skip to content

Commit 0277062

Browse files
authored
fix(translation): prevent duplicate locale error on server restart (medusajs#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.
1 parent 92d240d commit 0277062

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

.changeset/frank-days-start.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@medusajs/translation": patch
3+
---
4+
5+
fix(translation): prevent duplicate locale error on server restart

packages/modules/translation/src/loaders/defaults.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import {
33
Logger,
44
ModulesSdkTypes,
55
} from "@medusajs/framework/types"
6-
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
6+
import {
7+
ContainerRegistrationKeys,
8+
normalizeLocale,
9+
} from "@medusajs/framework/utils"
710
import Locale from "@models/locale"
811

912
/**
@@ -70,7 +73,24 @@ export default async ({ container }: LoaderOptions): Promise<void> => {
7073
container.resolve("localeService")
7174

7275
try {
73-
const resp = await localeService_.upsert(defaultLocales)
76+
// Fetch existing locales to map their IDs for upsert
77+
// The upsert method uses `id` as the key, so we need to include IDs for existing locales
78+
const existingLocales = await localeService_.list(
79+
{},
80+
{ select: ["id", "code"] }
81+
)
82+
const existingByCode = new Map(
83+
existingLocales.map((l) => [l.code, l.id])
84+
)
85+
86+
// Map default locales to include IDs for existing ones
87+
const localesToUpsert = defaultLocales.map((locale) => {
88+
const normalizedCode = normalizeLocale(locale.code)
89+
const existingId = existingByCode.get(normalizedCode)
90+
return existingId ? { ...locale, id: existingId } : locale
91+
})
92+
93+
const resp = await localeService_.upsert(localesToUpsert)
7494
logger.debug(`Loaded ${resp.length} locales`)
7595
} catch (error) {
7696
logger.warn(

0 commit comments

Comments
 (0)