From d09b6d4e14428b5c353901c2e4b89f4865a27a2a Mon Sep 17 00:00:00 2001 From: openclaw-agent Date: Fri, 12 Jun 2026 04:12:50 +0000 Subject: [PATCH] fix(core): coerce unknown material.preset to 'custom' (Sentry MONOREPO-EDITOR-DB) --- packages/core/src/schema/material.test.ts | 49 +++++++++++++++++++++++ packages/core/src/schema/material.ts | 3 +- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/schema/material.test.ts diff --git a/packages/core/src/schema/material.test.ts b/packages/core/src/schema/material.test.ts new file mode 100644 index 000000000..a6e521461 --- /dev/null +++ b/packages/core/src/schema/material.test.ts @@ -0,0 +1,49 @@ +import { describe, expect, test } from 'bun:test' +import { MaterialSchema } from './material' + +describe('MaterialSchema', () => { + describe('preset', () => { + test('valid preset passes through unchanged', () => { + const result = MaterialSchema.parse({ preset: 'brick' }) + expect(result.preset).toBe('brick') + }) + + test('every enum preset is accepted', () => { + const presets = [ + 'white', + 'brick', + 'concrete', + 'wood', + 'glass', + 'metal', + 'plaster', + 'tile', + 'marble', + 'custom', + ] as const + for (const preset of presets) { + expect(MaterialSchema.parse({ preset }).preset).toBe(preset) + } + }) + + test("unknown preset coerces to 'custom' instead of throwing (Sentry MONOREPO-EDITOR-DB)", () => { + const result = MaterialSchema.parse({ preset: 'stone' }) + expect(result.preset).toBe('custom') + }) + + test("non-string preset coerces to 'custom'", () => { + const result = MaterialSchema.parse({ preset: 42 }) + expect(result.preset).toBe('custom') + }) + + test('missing preset stays undefined', () => { + const result = MaterialSchema.parse({}) + expect(result.preset).toBeUndefined() + }) + + test('explicit undefined preset stays undefined', () => { + const result = MaterialSchema.parse({ preset: undefined }) + expect(result.preset).toBeUndefined() + }) + }) +}) diff --git a/packages/core/src/schema/material.ts b/packages/core/src/schema/material.ts index da82b68b2..0c8fcae5a 100644 --- a/packages/core/src/schema/material.ts +++ b/packages/core/src/schema/material.ts @@ -27,7 +27,8 @@ export type MaterialProperties = z.infer export const MaterialSchema = z.object({ id: z.string().optional(), - preset: MaterialPreset.optional(), + // Coerce unknown presets (legacy/AI-generated data) to 'custom' instead of throwing. + preset: MaterialPreset.catch('custom').optional(), properties: MaterialProperties.optional(), texture: z .object({