From 774d98ddad3123a7d12709ae029c853aea1b0039 Mon Sep 17 00:00:00 2001
From: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
Date: Fri, 17 Jul 2026 23:09:39 +0100
Subject: [PATCH] bugfix: trim archived map names (#4632)
## Description:
fixed a bug where "Deglaciated Antarctica" had a trailing space in an
earlier version of the game and caused visual issues:
and prevented stats from loading:
now works:
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
## Please put your Discord username so you can be contacted if a bug or
regression is found:
w.o.n
---
src/core/ApiSchemas.ts | 2 +-
src/core/ClanApiSchemas.ts | 2 +-
src/core/Schemas.ts | 4 ++++
tests/ApiSchemas.test.ts | 11 +++++++++++
tests/ArchivedRecordSchema.test.ts | 11 +++++++++++
tests/client/clan/ClanApiSchemas.test.ts | 11 +++++++++++
6 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/src/core/ApiSchemas.ts b/src/core/ApiSchemas.ts
index 0b74f86c0..219bb910a 100644
--- a/src/core/ApiSchemas.ts
+++ b/src/core/ApiSchemas.ts
@@ -246,7 +246,7 @@ export const PublicPlayerGameSchema = z.object({
gameId: z.string(),
start: z.iso.datetime(),
durationSeconds: z.number().int().nonnegative(),
- map: z.string(),
+ map: z.string().trim(),
mode: z.string(),
type: z.string(),
playerTeams: z.string().nullable(),
diff --git a/src/core/ClanApiSchemas.ts b/src/core/ClanApiSchemas.ts
index 0246e94d0..99da2b46c 100644
--- a/src/core/ClanApiSchemas.ts
+++ b/src/core/ClanApiSchemas.ts
@@ -198,7 +198,7 @@ export const ClanGameSchema = z.object({
gameId: z.string(),
start: z.iso.datetime(),
durationSeconds: z.number().int().nonnegative(),
- map: z.string().optional(),
+ map: z.string().trim().optional(),
mode: z.string().optional(),
// playerTeams is `null` (not absent) for FFA / non-team games — use
// `.nullish()` so the wire `null` doesn't fail the parse.
diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts
index 8daecd410..0bbb7e7b9 100644
--- a/src/core/Schemas.ts
+++ b/src/core/Schemas.ts
@@ -947,6 +947,10 @@ const ArchivedPlayerRecordSchema = PlayerRecordSchema.extend({
export const ArchivedAnalyticsRecordSchema = AnalyticsRecordSchema.extend({
info: GameEndInfoSchema.extend({
config: GameConfigSchema.extend({
+ gameMap: z.preprocess(
+ (value) => (typeof value === "string" ? value.trim() : value),
+ GameConfigSchema.shape.gameMap,
+ ),
// predates configurable nation count
nations: GameConfigSchema.shape.nations
.catch("default")
diff --git a/tests/ApiSchemas.test.ts b/tests/ApiSchemas.test.ts
index 8be21e42a..aa2d115e2 100644
--- a/tests/ApiSchemas.test.ts
+++ b/tests/ApiSchemas.test.ts
@@ -119,6 +119,17 @@ describe("PublicPlayerGameSchema", () => {
expect(PublicPlayerGameSchema.safeParse(validGame).success).toBe(true);
});
+ it("normalizes accidental whitespace around archived map names", () => {
+ const result = PublicPlayerGameSchema.safeParse({
+ ...validGame,
+ map: "Deglaciated Antarctica ",
+ });
+
+ expect(result.success).toBe(true);
+ if (!result.success) return;
+ expect(result.data.map).toBe("Deglaciated Antarctica");
+ });
+
it("accepts clanTag: null (not repping a clan)", () => {
expect(
PublicPlayerGameSchema.safeParse({ ...validGame, clanTag: null }).success,
diff --git a/tests/ArchivedRecordSchema.test.ts b/tests/ArchivedRecordSchema.test.ts
index ceb351459..8a9993a4c 100644
--- a/tests/ArchivedRecordSchema.test.ts
+++ b/tests/ArchivedRecordSchema.test.ts
@@ -95,4 +95,15 @@ describe("ArchivedAnalyticsRecordSchema", () => {
expect(result.data.info.players[0].clanTag).toBe("ABC");
expect(result.data.info.players[0].stats?.conquests).toEqual([1n, 2n, 0n]);
});
+
+ test("normalizes accidental whitespace around an archived map name", () => {
+ const record = oldRecord();
+ record.info.config.gameMap = "Deglaciated Antarctica ";
+
+ const result = ArchivedAnalyticsRecordSchema.safeParse(record);
+
+ expect(result.success).toBe(true);
+ if (!result.success) return;
+ expect(result.data.info.config.gameMap).toBe("Deglaciated Antarctica");
+ });
});
diff --git a/tests/client/clan/ClanApiSchemas.test.ts b/tests/client/clan/ClanApiSchemas.test.ts
index d66e13ea1..4207108aa 100644
--- a/tests/client/clan/ClanApiSchemas.test.ts
+++ b/tests/client/clan/ClanApiSchemas.test.ts
@@ -291,6 +291,17 @@ describe("ClanGameSchema", () => {
expect(ClanGameSchema.safeParse(validGame).success).toBe(true);
});
+ it("normalizes accidental whitespace around archived map names", () => {
+ const result = ClanGameSchema.safeParse({
+ ...validGame,
+ map: "Deglaciated Antarctica ",
+ });
+
+ expect(result.success).toBe(true);
+ if (!result.success) return;
+ expect(result.data.map).toBe("Deglaciated Antarctica");
+ });
+
it("accepts playerTeams: null (FFA / non-team games)", () => {
const result = ClanGameSchema.safeParse({
...validGame,