From 41208118e32da9014c383e58586b82747eafc282 Mon Sep 17 00:00:00 2001 From: Prince Jain Date: Thu, 22 Oct 2026 22:36:42 +0530 Subject: [PATCH 1/2] fix(core): parse run metadata returned as a JSON string GET /api/v1/runs/:runId/metadata returns the stored metadata string unparsed, while the response schema expects a record, so metadata.refresh() always failed validation. Accept a string payload and JSON.parse it before validating, keeping object responses and the rejection of non-JSON values unchanged. Fixes #5039 --- .changeset/run-metadata-json-string.md | 4 +++ packages/core/src/v3/schemas/api.ts | 15 ++++++++- .../core/src/v3/schemas/runMetadata.test.ts | 32 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 .changeset/run-metadata-json-string.md create mode 100644 packages/core/src/v3/schemas/runMetadata.test.ts diff --git a/.changeset/run-metadata-json-string.md b/.changeset/run-metadata-json-string.md new file mode 100644 index 00000000000..78bd1b37f9a --- /dev/null +++ b/.changeset/run-metadata-json-string.md @@ -0,0 +1,4 @@ +"@trigger.dev/core": patch +--- + +`metadata.refresh()` now works against deployments where `GET /api/v1/runs/:runId/metadata` returns the run metadata as a JSON string rather than an object. The response schema parses a string payload before validating, so `refresh()` resolves with the same metadata record on every version. diff --git a/packages/core/src/v3/schemas/api.ts b/packages/core/src/v3/schemas/api.ts index 9ec3cb24b84..fd0601fe5e7 100644 --- a/packages/core/src/v3/schemas/api.ts +++ b/packages/core/src/v3/schemas/api.ts @@ -1769,7 +1769,20 @@ export const UpdateMetadataRequestBody = FlushedRunMetadata; export type UpdateMetadataRequestBody = z.infer; export const UpdateMetadataResponseBody = z.object({ - metadata: z.record(z.string(), DeserializedJsonSchema), + metadata: z.preprocess( + (value) => { + if (typeof value !== "string") { + return value; + } + + try { + return JSON.parse(value); + } catch { + return value; + } + }, + z.record(z.string(), DeserializedJsonSchema) + ), }); export type UpdateMetadataResponseBody = z.infer; diff --git a/packages/core/src/v3/schemas/runMetadata.test.ts b/packages/core/src/v3/schemas/runMetadata.test.ts new file mode 100644 index 00000000000..c7e7e79327d --- /dev/null +++ b/packages/core/src/v3/schemas/runMetadata.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import { UpdateMetadataResponseBody } from "./api.js"; + +describe("UpdateMetadataResponseBody", () => { + it("parses an object metadata payload", () => { + const result = UpdateMetadataResponseBody.safeParse({ + metadata: { key: "value", count: 2 }, + }); + + expect(result.success).toBe(true); + if (result.success) { + expect(result.data.metadata).toEqual({ key: "value", count: 2 }); + } + }); + + it("parses a metadata payload returned as a JSON string", () => { + const result = UpdateMetadataResponseBody.safeParse({ + metadata: '{"key":"value","count":2}', + }); + + expect(result.success).toBe(true); + if (result.success) { + expect(result.data.metadata).toEqual({ key: "value", count: 2 }); + } + }); + + it("rejects a metadata payload that is neither object nor valid JSON", () => { + const result = UpdateMetadataResponseBody.safeParse({ metadata: "not-json" }); + + expect(result.success).toBe(false); + }); +}); From 6ba06cdac9610a377635ca52272b21ff2dddfd49 Mon Sep 17 00:00:00 2001 From: princejain756 Date: Thu, 22 Oct 2026 22:42:26 +0530 Subject: [PATCH 2/2] fix(changeset): add missing frontmatter delimiter --- .changeset/run-metadata-json-string.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/run-metadata-json-string.md b/.changeset/run-metadata-json-string.md index 78bd1b37f9a..bf9b228bc21 100644 --- a/.changeset/run-metadata-json-string.md +++ b/.changeset/run-metadata-json-string.md @@ -1,3 +1,4 @@ +--- "@trigger.dev/core": patch ---