fix(sprint): accept null start/finish from server (YT-2) #45

Merged
David merged 1 commit from fix/sprint-list-null-dates into main 2026-05-18 18:07:52 +02:00
Owner

Summary

YouTrack returns null for sprint start/finish when a sprint has no scheduled dates set. Bare i64 with #[serde(default)] rejects null because serde default only fires for missing fields, not explicit JSON null, so yt sprint list crashed with invalid type: null, expected i64 against any board that has a dateless sprint. This commit switches Sprint.start and Sprint.finish to Option<i64> so both null and missing become None, and updates the determine_current_sprint time-window check accordingly. The fallback comparator on b.finish.cmp(&a.finish) is unchanged because Option<T> orders None below Some(_), preserving the prior 0-as-sentinel ordering.

First of three items on YT-2. The yt sprint create and yt sprint update commands are still open on that issue and will land in follow-up PRs.

YouTrack

YT-2 (item 1 of 3, leaves issue in progress)

Test plan

  • New unit test list_sprints_tolerates_null_dates in src/yt/api.rs deserializes a sprint with "start":null,"finish":null via wiremock; this would have failed pre-fix.
  • just pre-commit runs fmt, clippy, build, test. One pre-existing unrelated test failure: commands::update::tests::check_writable_returns_friendly_message_on_readonly_dir fails on origin/main without these changes too. Looks like the test's USER=root skip guard is insufficient inside the rust-builder docker container; worth a separate ticket but out of scope here.
  • After merge, re-run yt sprint list --board "Investigator Database" against the isimcha.myjetbrains.com instance to confirm the live repro captured in the YT-2 comment thread is fixed.
## Summary YouTrack returns `null` for sprint `start`/`finish` when a sprint has no scheduled dates set. Bare `i64` with `#[serde(default)]` rejects `null` because serde default only fires for missing fields, not explicit JSON null, so `yt sprint list` crashed with `invalid type: null, expected i64` against any board that has a dateless sprint. This commit switches `Sprint.start` and `Sprint.finish` to `Option<i64>` so both `null` and missing become `None`, and updates the `determine_current_sprint` time-window check accordingly. The fallback comparator on `b.finish.cmp(&a.finish)` is unchanged because `Option<T>` orders `None` below `Some(_)`, preserving the prior `0`-as-sentinel ordering. First of three items on YT-2. The `yt sprint create` and `yt sprint update` commands are still open on that issue and will land in follow-up PRs. ## YouTrack YT-2 (item 1 of 3, leaves issue in progress) ## Test plan - [x] New unit test `list_sprints_tolerates_null_dates` in `src/yt/api.rs` deserializes a sprint with `"start":null,"finish":null` via wiremock; this would have failed pre-fix. - [x] `just pre-commit` runs fmt, clippy, build, test. One pre-existing unrelated test failure: `commands::update::tests::check_writable_returns_friendly_message_on_readonly_dir` fails on `origin/main` without these changes too. Looks like the test's `USER=root` skip guard is insufficient inside the rust-builder docker container; worth a separate ticket but out of scope here. - [ ] After merge, re-run `yt sprint list --board "Investigator Database"` against the isimcha.myjetbrains.com instance to confirm the live repro captured in the YT-2 comment thread is fixed.
fix(sprint): accept null start/finish from server (YT-2)
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 14s
Create release / Create release from merged PR (pull_request) Has been skipped
1b600c7af4
YouTrack returns null for sprint start/finish when a sprint has no scheduled dates, which crashed `yt sprint list` with `invalid type: null, expected i64`. Bare i64 with `#[serde(default)]` does not accept null; serde default only fires for missing fields, not for explicit JSON null.

Change `Sprint.start` and `Sprint.finish` from `i64` to `Option<i64>` so both null and missing become `None`. Update the `determine_current_sprint` time-window check in `sprint_resolution.rs` to handle the Option pair via a let-else guard. The fallback comparator `b.finish.cmp(&a.finish)` is unchanged because `Option<T>` orders `None` below `Some(_)`, preserving the prior `0`-as-sentinel ordering.

First of three items on YT-2; `yt sprint create` and `yt sprint update` are still open on that issue.

#YT-2
David merged commit 0d5226062b into main 2026-05-18 18:07:52 +02:00
David deleted branch fix/sprint-list-null-dates 2026-05-18 18:07:52 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pandoras-box/youtrack-cli!45
No description provided.