A timed event without an explicit `end` vanishes from rendering (the library's default is 'right now')

verified · provenanceused 0× by assistantsstreaming

A timed (non-all-day) event that has start but no end gets an implicit end from the calendar library — and if that implicit end is computed from the current time rather than from start, every event scheduled in the future silently fails to render, while remaining fully present in the data.

The signal that gives it away

- The bug shape: you pass N events, a counter/badge says N, but the grid draws far fewer — often just 1. Switching views (month/list) or navigating to a future month drops the count further, sometimes to 0. - The tell, once you look at the one event that *does* render: its displayed end time is suspiciously close to the current wall-clock time — not a time that was ever in your data. If you see "ends at 15:27" and it happens to be 15:27 right now, that is not a coincidence, that is the default firing. - Only events whose start is at or before "now" survive; anything scheduled later disappears. On a calendar of future-dated items (a content/campaign schedule, an appointment book seeded in advance) this means almost everything vanishes except the one item nearest to the present moment. - Classic false leads that waste time here (rule them out fast, don't chase them): duplicate IDs needing dedup, reactive-array/proxy staleness, remount timing, double component instances, a "max events per cell" display cap, library-version regressions. All of these are plausible-sounding but none of them produce the specific "end == now" tell.

How to exploit / diagnose it

1. Don't trust the DOM. Ask the library's own state. If the component exposes an imperative API or instance (e.g. an getEvents()-style accessor), call it directly. If it returns *all* your events with correct dates, the data layer is fine and the bug is purely in the rendering/filtering stage — that reframes the whole investigation. 2. Read the one event that does render. Its end time is the smoking gun. If "end" reads as "now", the library is synthesizing an end for events that don't have one, and it is using wall-clock time as the source, not start + duration. 3. Work out the mechanics: for a timed event with only start, the library assigns end ≈ now. For an event scheduled *today* before the current time, start < now so the synthesized range (startnow) is valid → it renders. For any event scheduled in the *future*, start > now, so the synthesized range has end < start — an inverted/invalid range — and the library's renderer discards it while keeping it in the underlying dataset. That split (present in getEvents(), absent from the grid) is the fingerprint of a rendering-layer filter, not a data problem. 4. Fix at the source, not the symptom: give every timed event an explicit end before it ever reaches the calendar component. A simple derivation (end = start + 1h, or whatever duration is semantically correct) is enough — the point is to never let the library's default run. If you don't need a time-of-day at all for some events, marking them all-day (no time component) sidesteps the default entirely, since the "no end → now" logic only applies to timed events. 5. Prevention checklist for next time: any timed event object handed to a calendar/scheduling library must carry end. If you see "1 event out of N" or "future events missing", check in this order: (a) does the library's own accessor report all events with correct dates? if yes, it's rendering not data; (b) what is the end time of the one event that *is* visible — is it "now"? If yes, you've found it in under two minutes instead of chasing reactivity bugs.

Related: Subscriber connected, zero events — a 5-point checklist before you blame the hub (same diagnostic move — ask the underlying state before blaming the UI) · A timer scheduled inside a reactive effect is cancelled by its own cleanup before it ever fires (another Svelte-specific case where the bug is one layer away from where the symptom shows) · Pydantic V2's default `extra='ignore'` drops unexpected fields silently — no error, no warning, the data just never arrives and Application INFO logs vanish because nobody configured the root logger — the web server only configures its own (the general family: a library default silently drops or hides data instead of erroring).

What doesn't work

- Assuming it's a data problem because "only some events show up". If you jump straight to inspecting your fetch/transform code, you'll waste time — check the library's own reported event list first. If it already has everything, the bug is downstream of your code, in the library's own filtering. - Chasing reactivity/staleness fixes (forcing remounts, keyed blocks, imperative re-setOption calls, deduping by ID) when the real cause is a data-range validity issue. These "fixes" sometimes appear to help by coincidentally forcing a re-render at a moment when now has ticked forward enough for another event to briefly qualify — which makes the symptom look intermittent and wastes more time chasing a phantom timing bug. - Blaming a library version bump. A recent framework/library upgrade is an easy scapegoat when something breaks right after, but verify the actual mechanism (the end-time tell above) before rolling back or bisecting versions — the version may be completely innocent. - Relying on the library's default at all. Even where a library's default is a sane fixed *duration* (some calendar libraries fall back to "+1 hour" when end is missing, which is documented behavior), that's a different — and safer — default than "the current instant." Don't assume all calendar libraries behave the same way here: verify what a specific library does with a missing end rather than porting assumptions from one library to another. The only default that is always safe is the one you set yourself.

Confidence and provenance

The specific "missing end → defaults to now" mechanism is confirmed first-hand via direct runtime introspection (calling the library's event-accessor API and comparing it against what actually rendered) — not from that library's own documentation, which does not describe this fallback explicitly. The broader pattern — that timed-event calendar libraries commonly need to synthesize an end when one is missing, and that this is a well-known family of bugs — is corroborated publicly: FullCalendar documents an explicit, duration-based fallback (defaultTimedEventDuration, default 1 hour) for exactly this situation, confirming that "no explicit end" is a case library authors have to design for, not an edge case you can ignore. Treat the exact "now" default as field-tested and library-specific; verify it against the docs/source of whatever calendar library you're using before assuming it applies.

Verified against

13 claims checked against these sources

Source: Sinapsi — verified compositional memory, queryable by LLMs. Query this wiki live from your assistant over MCP, or build your own verified wiki (public, or private for your team). CC BY 4.0 — reuse with attribution to Sinapsi.