gs.beginningOfLast2Years() — Behaviour & Archive Rule ImpactIssue <!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Administrators report records being archived earlier than expected by archive rules whose conditions reference gs.beginningOfLast2Years(). The function name suggests "2 years ago", leading to an assumption that records remain available for a full two-year buffer before archival. In practice, gs.beginningOfLast2Years() returns the same value as gs.beginningOfLastYear() — January 1 of the previous calendar year. Records closed in December of the year-before-last become eligible for archival as soon as the rule runs after the new year. Symptoms<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Observed Behaviour A record (commonly a Request or Requested Item) is archived sooner than expected, often within days or weeks of the new yearThe archived record has a closed_at value in December of two calendar years prior (for example, closed 2024-12-26, archived 2026-01-01)Child Requested Items appear missing from their live table even though they were still in Open state at the time of archivalThe archive rule condition is read as closed_at < gs.beginningOfLast2Years(), and the threshold is assumed to be two full calendar yearsActivity logs on the archived record may show post-close state changes with timestamps at or near the archive event What Is Not Affected No data loss — archived records remain retrievable from the archive tableNo data corruption — all field values are preserved through the archive copyOpen records on the parent table are unaffected unless their parent qualifies and they are cascaded by a child rule Key Diagnostic Signal ObservationSignificanceArchived record has closed_at just before January 1 of last year (e.g. 2024-12-26 archived in 2026)Confirms the threshold is Jan 1 of last year, not Jan 1 of 2 years agoA child record was Open at archive time but still got cascadedConfirms the child archive rule cascades from the parent regardless of the child's own stateThe UI filter "Last 2 Years" decodes to beginningOfLastYear()@endOfThisYear()Confirms that "2 Years" refers to the window width, not the lookback depth Facts<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Function Behaviour FunctionReturns (called on 2026-05-14)Notesgs.beginningOfLastYear()2025-01-01 00:00:00 (server TZ)Canonical behaviourgs.beginningOfLast2Years()2025-01-01 00:00:00 (server TZ)Returns the same value as beginningOfLastYear()gs.endOfLast2Years()2026-12-31 23:59:59Returns the same value as endOfThisYear() The "Last 2 Years" UI Filter When selected from the date filter picker, the "Last 2 Years" option produces the following encoded query pair: javascript:gs.beginningOfLastYear() @ javascript:gs.endOfThisYear() This pair defines a two-calendar-year window from the start of last year through the end of this year. The "2 Years" label describes the span of the window, not how far back the start boundary sits. Reference Table — Value by Calendar Year Year the rule runsgs.beginningOfLast2Years() returnsArchive threshold: closed_at < …Any date in 20232022-01-01 00:00:00Before 2022-01-01Any date in 20242023-01-01 00:00:00Before 2023-01-01Any date in 20252024-01-01 00:00:00Before 2024-01-01Any date in 2026 ← current2025-01-01 00:00:00Before 2025-01-01Any date in 20272026-01-01 00:00:00Before 2026-01-01 Release<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } N/A Cause<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Root Cause The function gs.beginningOfLast2Years() is misleadingly named. By design, it returns the same value as gs.beginningOfLastYear() — January 1 of (current year − 1). The "2 Years" in the name refers to the width of the date range produced when paired with gs.endOfLast2Years(), not to how far back the start boundary sits. Contributing Factors FactorImpactFunction name reads as "2 years ago"Administrators write archive conditions assuming a 2-year buffer that doesn't existUI filter labelled "Last 2 Years"Reinforces the misconception when admins inspect encoded queriesRecords closed in late December of year N-2Fall just inside the archive threshold the moment the rule runs in year NChild cascade rules with permissive conditionsChild records (such as Requested Items or Catalog Tasks) follow the parent into the archive regardless of their own state Why the Window Is Called "Last 2 Years" When used as a range filter, the function pair produces a window spanning two full calendar years: BoundaryFunctionValue (called on 2026-05-14)Startgs.beginningOfLast2Years()2025-01-01 00:00:00Endgs.endOfLast2Years()2026-12-31 23:59:59 The window is two years wide (2025 + 2026), but its start is only one year back. Archive rules that use only the start boundary inherit this one-year lookback. Resolution<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Confirming an Archive Was Correct Identify the archived record's closed_at value and the archive rule's conditionCompute the threshold: January 1 of (year the rule ran − 1) — for example, if the rule ran in 2026, the threshold is 2025-01-01If closed_at < threshold and the record was inactive at the time, the archival matches the documented behaviourFor cascaded children, check the child archive rule's condition — children are typically swept in based on the parent's eligibility, regardless of the child's own state Worked Example Consider a Request closed on 2024-12-26. When the archive rule runs on 2026-01-01, the threshold is 2025-01-01: Condition CheckRecord ValueThresholdResultactive = falsefalse (closed)—PASSclosed_at < gs.beginningOfLast2Years()2024-12-262025-01-01 00:00:00PASS (by 5 days)request_state IN [closed_*]closed_complete—PASS The Request is correctly archived. It was closed only five days before the threshold, but those five days place it inside the archive condition. Long-Term Prevention ActionPurposeIf a true 2-year retention buffer is required, replace gs.beginningOfLast2Years() with an explicit expression such as gs.daysAgoStart(730) or a relative-date filter (e.g. closed_atRELATIVELT@year@ago@2)Eliminates the December-of-year-before-last edge caseAudit existing archive rules and document the actual retention each one provides — not the retention implied by the function nameSurfaces other rules with the same misalignmentReview child cascade conditions and confirm whether Open child records should be cascaded with their parentPrevents unexpected archival of active child recordsWhen verifying eligibility for a specific record, compare closed_at against January 1 of (current year − 1)Correct first-pass triage Expected Outcome: Where the archival matches the documented threshold, the platform is operating correctly and the resolution is administrator awareness. Where a true 2-year buffer is required, update the archive rule's condition to use an explicit 2-year expression. Watch Out — Child Cascade: Child records (such as Requested Items or Catalog Tasks) tied to a parent via cascade rules may be archived purely on the parent's eligibility. An Open child record can be archived if its parent qualifies. This is documented platform behaviour.