From d0232f2f855adeb3f1018e650b7bfda48d88caf8 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Fri, 2 Oct 2026 12:46:19 -0700 Subject: [PATCH 1/7] docs(nestjs): Document SentryCron monitor config from @Cron Co-Authored-By: Claude Opus 5.5 --- includes/nestjs-sentry-cron-decorator.mdx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/includes/nestjs-sentry-cron-decorator.mdx b/includes/nestjs-sentry-cron-decorator.mdx index d76734fbd7c86f..db37526a8a2612 100644 --- a/includes/nestjs-sentry-cron-decorator.mdx +++ b/includes/nestjs-sentry-cron-decorator.mdx @@ -29,3 +29,24 @@ export class MyCronService { } ``` + +### Monitor Config From `@Cron` + + + +If you don't pass a monitor config, `@SentryCron` takes the schedule and `timeZone` from the `@Cron` decorator on the same method and sends them with each check-in, so Sentry creates the monitor on the first run: + +```typescript +import { Cron } from '@nestjs/schedule'; +import { SentryCron } from '@sentry/nestjs'; + +export class MyCronService { + @Cron('0 * * * *', { timeZone: 'America/Los_Angeles' }) + @SentryCron('my-monitor-slug') + handleCron() { + // Your cron job logic here + } +} +``` + +A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Sub-minute schedules, presets such as `@daily`, `Date` values, and `utcOffset` send no monitor config. In those cases, pass a monitor config to `@SentryCron` or create the monitor in Sentry first. A monitor config passed to `@SentryCron` always takes precedence. From 394cbaf83f793494db6aa0f348ad6511acc60cf5 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Fri, 2 Oct 2026 12:57:48 -0700 Subject: [PATCH 2/7] docs(nestjs): Show fromCronDecorator opt-in for SentryCron Co-Authored-By: Claude Opus 5.5 --- includes/nestjs-sentry-cron-decorator.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/nestjs-sentry-cron-decorator.mdx b/includes/nestjs-sentry-cron-decorator.mdx index db37526a8a2612..178c86b125db0d 100644 --- a/includes/nestjs-sentry-cron-decorator.mdx +++ b/includes/nestjs-sentry-cron-decorator.mdx @@ -34,7 +34,7 @@ export class MyCronService { -If you don't pass a monitor config, `@SentryCron` takes the schedule and `timeZone` from the `@Cron` decorator on the same method and sends them with each check-in, so Sentry creates the monitor on the first run: +Instead of repeating the schedule, pass `{ fromCronDecorator: true }` to `@SentryCron`. It then takes the schedule and `timeZone` from the `@Cron` decorator on the same method and sends them with each check-in, so Sentry creates the monitor on the first run. You can set other monitor options, such as `checkinMargin` and `maxRuntime`, next to it: ```typescript import { Cron } from '@nestjs/schedule'; @@ -42,11 +42,11 @@ import { SentryCron } from '@sentry/nestjs'; export class MyCronService { @Cron('0 * * * *', { timeZone: 'America/Los_Angeles' }) - @SentryCron('my-monitor-slug') + @SentryCron('my-monitor-slug', { fromCronDecorator: true, checkinMargin: 2 }) handleCron() { // Your cron job logic here } } ``` -A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Sub-minute schedules, presets such as `@daily`, `Date` values, and `utcOffset` send no monitor config. In those cases, pass a monitor config to `@SentryCron` or create the monitor in Sentry first. A monitor config passed to `@SentryCron` always takes precedence. +A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Sub-minute schedules, presets such as `@daily`, `Date` values, and `utcOffset` send no monitor config. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. From eb6bf60899f3e26ca3441cbb4e4438b3e3db21e1 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Fri, 2 Oct 2026 13:09:08 -0700 Subject: [PATCH 3/7] docs(nestjs): SentryCron sends the @Cron schedule by default Co-Authored-By: Claude Opus 5.5 --- includes/nestjs-sentry-cron-decorator.mdx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/includes/nestjs-sentry-cron-decorator.mdx b/includes/nestjs-sentry-cron-decorator.mdx index 178c86b125db0d..5f5b993e260abc 100644 --- a/includes/nestjs-sentry-cron-decorator.mdx +++ b/includes/nestjs-sentry-cron-decorator.mdx @@ -34,7 +34,7 @@ export class MyCronService { -Instead of repeating the schedule, pass `{ fromCronDecorator: true }` to `@SentryCron`. It then takes the schedule and `timeZone` from the `@Cron` decorator on the same method and sends them with each check-in, so Sentry creates the monitor on the first run. You can set other monitor options, such as `checkinMargin` and `maxRuntime`, next to it: +If you don't pass a monitor config with a `schedule`, `@SentryCron` sends the schedule and time zone of the `@Cron` decorator on the same method with each check-in, so Sentry creates the monitor on the first run. You can still pass other monitor options, such as `checkinMargin` and `maxRuntime`: ```typescript import { Cron } from '@nestjs/schedule'; @@ -42,11 +42,15 @@ import { SentryCron } from '@sentry/nestjs'; export class MyCronService { @Cron('0 * * * *', { timeZone: 'America/Los_Angeles' }) - @SentryCron('my-monitor-slug', { fromCronDecorator: true, checkinMargin: 2 }) + @SentryCron('my-monitor-slug', { checkinMargin: 2 }) handleCron() { // Your cron job logic here } } ``` +If `@Cron` has no `timeZone`, the job runs in your server's local time zone, so that time zone is sent. + A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Sub-minute schedules, presets such as `@daily`, `Date` values, and `utcOffset` send no monitor config. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. + +To send check-ins without a monitor config, pass `{ fromCronDecorator: false }`. From 908b14c280800023f4530be5d227fa8f818c5e1b Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Fri, 2 Oct 2026 13:28:21 -0700 Subject: [PATCH 4/7] docs(nestjs): Note that @Cron presets are sent Co-Authored-By: Claude Opus 5.5 --- includes/nestjs-sentry-cron-decorator.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/nestjs-sentry-cron-decorator.mdx b/includes/nestjs-sentry-cron-decorator.mdx index 5f5b993e260abc..81bceef4f023d0 100644 --- a/includes/nestjs-sentry-cron-decorator.mdx +++ b/includes/nestjs-sentry-cron-decorator.mdx @@ -51,6 +51,6 @@ export class MyCronService { If `@Cron` has no `timeZone`, the job runs in your server's local time zone, so that time zone is sent. -A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Sub-minute schedules, presets such as `@daily`, `Date` values, and `utcOffset` send no monitor config. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. +A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Presets such as `@daily` and `@weekly` are sent too. Sub-minute schedules, `Date` values, and `utcOffset` send no monitor config, including any other options you pass. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. To send check-ins without a monitor config, pass `{ fromCronDecorator: false }`. From d33c58d533945c00cec71b71866bc4e34981038f Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Fri, 2 Oct 2026 15:02:23 -0700 Subject: [PATCH 5/7] docs(nestjs): List more @Cron schedules that send no monitor config Co-Authored-By: Claude --- includes/nestjs-sentry-cron-decorator.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/nestjs-sentry-cron-decorator.mdx b/includes/nestjs-sentry-cron-decorator.mdx index 81bceef4f023d0..5db65583951ee2 100644 --- a/includes/nestjs-sentry-cron-decorator.mdx +++ b/includes/nestjs-sentry-cron-decorator.mdx @@ -51,6 +51,6 @@ export class MyCronService { If `@Cron` has no `timeZone`, the job runs in your server's local time zone, so that time zone is sent. -A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Presets such as `@daily` and `@weekly` are sent too. Sub-minute schedules, `Date` values, and `utcOffset` send no monitor config, including any other options you pass. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. +A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Presets such as `@daily` and `@weekly` are sent too. Sub-minute schedules, `Date` values, `utcOffset`, numeric months (use names such as `MAY`), a `*/n` day field combined with the other day field, and time zones that aren't IANA names send no monitor config, including any other options you pass. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. To send check-ins without a monitor config, pass `{ fromCronDecorator: false }`. From 11ed2d367cfddcf4ba45ae195319defe29c76518 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Mon, 5 Oct 2026 12:24:08 -0700 Subject: [PATCH 6/7] docs(nestjs): Note billing and schedule overwrite, allow month steps Co-Authored-By: Claude --- includes/nestjs-sentry-cron-decorator.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/includes/nestjs-sentry-cron-decorator.mdx b/includes/nestjs-sentry-cron-decorator.mdx index 5db65583951ee2..33149550cb4da4 100644 --- a/includes/nestjs-sentry-cron-decorator.mdx +++ b/includes/nestjs-sentry-cron-decorator.mdx @@ -51,6 +51,8 @@ export class MyCronService { If `@Cron` has no `timeZone`, the job runs in your server's local time zone, so that time zone is sent. -A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Presets such as `@daily` and `@weekly` are sent too. Sub-minute schedules, `Date` values, `utcOffset`, numeric months (use names such as `MAY`), a `*/n` day field combined with the other day field, and time zones that aren't IANA names send no monitor config, including any other options you pass. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. +The monitor is created, and billed, on the first run. Each check-in overwrites the monitor's schedule and time zone with the ones from `@Cron`, so change them in your code rather than in Sentry. + +A six-field expression is sent without its seconds field if that field is a single number, such as `0 30 9 * * *`. Presets such as `@daily` and `@weekly` are sent too. Sub-minute schedules, `Date` values, `utcOffset`, month numbers (use names such as `MAY`; steps such as `*/3` work), a `*/n` or full-range day field (such as `1-31`) combined with the other day field, and time zones that aren't IANA names send no monitor config, including any other options you pass. In those cases, pass a full monitor config to `@SentryCron` or create the monitor in Sentry first. To send check-ins without a monitor config, pass `{ fromCronDecorator: false }`. From 6d0ffeefb9d7da6c4c4765ad653b0175da579590 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Mon, 5 Oct 2026 17:45:29 -0700 Subject: [PATCH 7/7] docs(nestjs): Note utcOffset is not sent as the local time zone Co-Authored-By: Claude --- includes/nestjs-sentry-cron-decorator.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/nestjs-sentry-cron-decorator.mdx b/includes/nestjs-sentry-cron-decorator.mdx index 33149550cb4da4..1c678107a0de95 100644 --- a/includes/nestjs-sentry-cron-decorator.mdx +++ b/includes/nestjs-sentry-cron-decorator.mdx @@ -49,7 +49,7 @@ export class MyCronService { } ``` -If `@Cron` has no `timeZone`, the job runs in your server's local time zone, so that time zone is sent. +If `@Cron` has neither `timeZone` nor `utcOffset`, the job runs in your server's local time zone, so that time zone is sent. The monitor is created, and billed, on the first run. Each check-in overwrites the monitor's schedule and time zone with the ones from `@Cron`, so change them in your code rather than in Sentry.