diff --git a/apps/backend/src/lib/seed-dummy-data.ts b/apps/backend/src/lib/seed-dummy-data.ts index 5b5784278..479cd1088 100644 --- a/apps/backend/src/lib/seed-dummy-data.ts +++ b/apps/backend/src/lib/seed-dummy-data.ts @@ -1983,7 +1983,7 @@ async function seedSamlConnections(projectId: string): Promise { // dot-keys — config normalization with onDotIntoNonObject="ignore" // drops dot-keys that try to navigate into a record entry that // doesn't yet exist (same convention as auth.oauth.providers). - const overlay: Record = {}; + const overlay: Parameters[0]["environmentConfigOverrideOverride"] = {}; for (const f of fetched) { overlay[`auth.saml.connections.${f.slug}`] = { displayName: f.displayName, @@ -1998,7 +1998,7 @@ async function seedSamlConnections(projectId: string): Promise { await overrideEnvironmentConfigOverride({ projectId, branchId: DEFAULT_BRANCH_ID, - environmentConfigOverrideOverride: overlay as Parameters[0]["environmentConfigOverrideOverride"], + environmentConfigOverrideOverride: overlay, }); } @@ -2131,7 +2131,6 @@ export async function seedDummyProject(options: SeedDummyProjectOptions): Promis "payments.testMode": true, }, }), - ...(getEnvVariable("STACK_SEED_ENABLE_SAML", "false") === "true" ? [seedSamlConnections(projectId)] : []), ...options.skipGithubConfigSource ? [] : [setBranchConfigOverrideSource({ projectId, branchId: DEFAULT_BRANCH_ID, @@ -2154,6 +2153,16 @@ export async function seedDummyProject(options: SeedDummyProjectOptions): Promis }), ]); + // Run sequentially after the parallel block. Both this and the + // `payments.testMode` write above target the same environment config, + // and `overrideEnvironmentConfigOverride` is read-modify-write — running + // them in parallel races and one write clobbers the other (TODO at + // config.ts:491 already documents this). Sequencing avoids the race + // until the underlying override is wrapped in a serializable txn. + if (getEnvVariable("STACK_SEED_ENABLE_SAML", "false") === "true") { + await seedSamlConnections(projectId); + } + await seedDummyTransactions({ prisma: dummyPrisma, tenancyId: dummyTenancy.id,