Bug in BYSETPOS
- Dominant language
- JavaScript
- Stars
- 1.2k
- Forks
- 156
- Avg merge
- 4d 43m
- Merged PRs (30d)
- 3
Description
This is regarding the latest tagged release v2.2.1, which is the same as is currently being used (as of writing this, on 2026-02-08) on your tester tool page [https://kewisch.github.io/ical.js/recur-tester.html](https://kewisch.github.io/ical.js/recur-tester.html).
I cannot get any BYSETPOS values to work.
The use case I ran into this with was in trying to create a recurrence rule which effectively meant "Give me the Nth day of each month, or the last day of that month if there are less than N days in that month."
The correct answer to this (for values of N >= 28 anyway, done for brevity's sake in this example), at least according to how I understand the iCalendar/RFC5545 standard, is:
`RRULE:FREQ=MONTHLY;BYMONTHDAY={28..N};BYSETPOS=-1`
where the `{28..N}` is meant to say "the list of numbers from 28 to N"
So if you wanted the 30 day of the month, or the last day of the month for months that don't have that many days, it would be:
`RRULE:FREQ=MONTHLY;BYMONTHDAY=28,29,30;BYSETPOS=-1`
but I was puzzled by what I saw in the results:
As you can see, yes it did produce the correct result, but it was mixed in with invalid results as well. I thought at first I had my logic in constructing the RRULE string wrong, but I've double and triple-checked; it's right. (I checked with other implementations which validate this).
What I've come to realize is that it appears as though the BYSETPOS portion of the rule is simply ignored completely. Look at those results again and think what would happen if that BYSETPOS simply wasn't there... _then_ the results would be 100% correct.
I verified this by giving it a simpler test (notice I changed the start and end dates to be New Year's at midnight to make it as simple as possible to reason about):
And again, it appears as if the BYSETPOS portion of the RRULE is just completely ignored.
Contributor guide
Research direction
Reproduce the report in the ical.js recurrence tester at https://kewisch.github.io/ical.js/recur-tester.html using the supplied RRULE examples. Compare results with and without BYSETPOS, then trace the recurrence entry point that parses and expands the rule. Done means BYSETPOS is honored and only the selected monthly dates are returned.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100