Skip to content

Commit 736c235

Browse files
committed
fix(mcp-common): make outcome optional in observability event schema
zCloudflareMiniEvent required outcome on every event, but outcome only describes an invocation and is absent on console.log lines emitted inside one. query_worker_observability validates the whole event array in a single .parse(), so any response containing one of these non-invocation events was rejected outright and no logs were returned. Fixes #418
1 parent e1b9c17 commit 736c235

3 files changed

Lines changed: 56 additions & 1 deletion

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@repo/mcp-common': patch
3+
---
4+
5+
fix(mcp-common): make `outcome` optional in the Workers Observability response schema
6+
7+
`zCloudflareMiniEvent` (`packages/mcp-common/src/types/workers-logs.types.ts`) required every event to carry `outcome`, but `outcome` only describes a whole invocation and is absent on the `console.log` lines emitted inside one. Because `query_worker_observability` validates the entire event array in a single `.parse()`, any response containing one of these non-invocation events was rejected outright and the tool returned no logs at all. `outcome` is now optional so responses with a mix of invocation and non-invocation events parse correctly.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { describe, expect, it } from 'vitest'
2+
3+
import { zCloudflareMiniEvent, zReturnedQueryRunEvents } from './workers-logs.types'
4+
5+
describe('zCloudflareMiniEvent', () => {
6+
it('parses a console.log event with no outcome', () => {
7+
const event = {
8+
event: {},
9+
scriptName: 'my-worker',
10+
eventType: 'cron',
11+
requestId: '1RI7X6A7OCMC159U',
12+
}
13+
expect(() => zCloudflareMiniEvent.parse(event)).not.toThrow()
14+
})
15+
16+
it('still parses an invocation-summary event with an outcome', () => {
17+
const event = {
18+
event: {},
19+
scriptName: 'my-worker',
20+
eventType: 'cron',
21+
requestId: '1RI7X6A7OCMC159U',
22+
outcome: 'ok',
23+
}
24+
expect(zCloudflareMiniEvent.parse(event).outcome).toBe('ok')
25+
})
26+
})
27+
28+
describe('zReturnedQueryRunEvents', () => {
29+
it('does not discard the batch when one event has no outcome', () => {
30+
const telemetryEvent = (workers: Record<string, unknown>) => ({
31+
dataset: 'cloudflare-workers',
32+
timestamp: 1784222146000,
33+
source: 'log line',
34+
$workers: {
35+
event: {},
36+
scriptName: 'my-worker',
37+
eventType: 'cron',
38+
requestId: '1RI7X6A7OCMC159U',
39+
...workers,
40+
},
41+
$metadata: { id: 'evt-1' },
42+
})
43+
const result = zReturnedQueryRunEvents.parse({
44+
events: [telemetryEvent({}), telemetryEvent({ outcome: 'ok' })],
45+
})
46+
expect(result.events).toHaveLength(2)
47+
})
48+
})

packages/mcp-common/src/types/workers-logs.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ const zCloudflareMiniEventDetails = z.object({
248248
export const zCloudflareMiniEvent = z.object({
249249
event: zCloudflareMiniEventDetails,
250250
scriptName: z.string(),
251-
outcome: z.string(),
251+
outcome: z.string().optional(),
252252
eventType: z.enum([
253253
'fetch',
254254
'scheduled',

0 commit comments

Comments
 (0)