Get this on every PR automatically. Webhook fires, AI reviews, you approve.
Install on vercel/eve →
// reviewed by pulllight
PullLight found 3 issues
1 high
2 medium
// convert to your repo
PullLight caught 3 1 high, 2 medium on this PR.
Install on vercel/eve to get this on every PR automatically — 60 seconds.
Findings
3 issues
high
logic
`activeTurnId` is read by `toLifecycleEvent` before it is updated for `turn.started` events. On line 27, `toLifecycleEvent` is called with the old (undefined) `activeTurnId`, and only on line 28 is `activeTurnId` set to `event.data.turnId`. This means the `turn.started` lifecycle event is published with `turnId: undefined` instead of the correct turn ID. The assignment should happen before the call to `toLifecycleEvent`.
// packages/eve/src/harness/instrumentation-native-events.ts:28
⚡ Suggested fix
await handleEvent(event, messages);
if (event.type === "turn.started") activeTurnId = event.data.turnId;
const lifecycleEvent = toLifecycleEvent(event, input, activeTurnId);
if (lifecycleEvent !== undefined) await hooks.publish(lifecycleEvent);
medium
logic
When `executeModelCall()` throws, `rethrowNoOutputAsEmptyResponse(error)` is called and its return value is returned. However, `rethrowNoOutputAsEmptyResponse` is designed to re-throw (its name implies it always throws or rethrows), so if it does not throw for a given error, the `attempt.failed` event is published but the caller receives a resolved promise with whatever `rethrowNoOutputAsEmptyResponse` returns — silently swallowing the error. The original code used `.catch(rethrowNoOutputAsEmptyResponse)` which preserved the rejection chain correctly. Verify that returning the result of `rethrowNoOutputAsEmptyResponse` is intentional and covers all error cases.
// packages/eve/src/harness/tool-loop.ts:1051
medium
logic
`createInstrumentationHandleEvent` is called inside the step function (per-step), which means a new closure with a fresh `activeTurnId = undefined` is created on every step invocation. If the same session progresses through multiple steps, `activeTurnId` will never carry over between steps, so `session.waiting`/`session.completed`/`session.failed` lifecycle events emitted in a later step will have `turnId: undefined`. Consider hoisting this call outside the per-step closure, or passing the active turn ID explicitly.
// packages/eve/src/harness/tool-loop.ts:539