Skip to content

Bug: @novu/api SubscriberResponseDto Zod schema requires lastOnlineAt and isOnline but API returns undefined #10452

@anthonysette

Description

@anthonysette

Description

The @novu/api@3.14.2 package's generated Zod schemas for SubscriberResponseDto mark lastOnlineAt and isOnline as required (nullable but not optional). However, the Novu API returns responses where these fields are undefined for newly created subscribers who have never been online, causing a ZodError on the client side.

This is similar to the fix in #8538 which made fields nullable — but lastOnlineAt and isOnline also need to be .optional() since the API omits them entirely in some cases.

Reproduction steps

  1. Install @novu/api@3.14.2
  2. Create a new subscriber via novu.subscribers.create({ subscriberId: 'test', firstName: 'Test', email: 'test@example.com' })
  3. The API call succeeds on Novu's side, but the SDK throws a ZodError when parsing the response

Expected behavior

subscribers.create() should resolve successfully. The lastOnlineAt and isOnline fields should be optional in the Zod schema since not all subscribers have these values set.

Actual behavior

A ZodError is thrown:

ZodError: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": ["Result", "lastOnlineAt"],
    "message": "Required"
  }
]

Proposed fix

In the following files, add .optional() to both fields:

  • models/components/subscriberresponsedto.js
  • models/components/subscriberresponsedtooptional.js
  • models/errors/subscriberresponsedto.js
- isOnline: z.nullable(z.boolean()),
- lastOnlineAt: z.nullable(z.string()),
+ isOnline: z.nullable(z.boolean()).optional(),
+ lastOnlineAt: z.nullable(z.string()).optional(),

Since the SDK is generated by Speakeasy from the OpenAPI spec, the root cause is likely that isOnline and lastOnlineAt are marked as required in the spec when they should not be.

Novu version

@novu/api@3.14.2 (latest)

node version

22

Additional context

Workaround: using pnpm patch to add .optional() to both fields.

  • I checked and didn't find a similar issue
  • I have read the contributing guidelines

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions