Two Bugs at the Edge: Fixing Contact Times for Graze-Zone Observers
When you stand near the limit of the totality path — where totality lasts only seconds — the same algorithm that works perfectly in the middle of the path starts lying in subtle ways.
When you're standing in the middle of totality's path, the eclipse math is forgiving. Contact times agree between tools. Corrections converge cleanly. But move toward the edge — where totality narrows to a handful of seconds — and the same algorithm starts producing wrong answers in ways that are hard to notice until you look specifically.
We found and fixed two bugs in eclipseClick's contact time resolver, both of which affect observers near the limits of the totality path. This post explains what went wrong and why.
How the Solver Decides Whether Totality Occurs
eclipseClick computes contact times using the Besselian element method. The Moon's shadow sweeps across a reference plane through Earth's center; at any observer location, the solver tracks a single number: m — the distance between the shadow axis and the observer in the fundamental plane. Contact occurs when m equals the shadow's radius.
At the moment of closest approach (maximum eclipse), m reaches its minimum — call it mmax. Whether that minimum is smaller or larger than L2 determines what the observer sees:
In theory this is clean. In practice, it broke in two ways for observers near the edge.
Bug 1 — False Totality for Outside-Path Observers
Before attempting a C2/C3 solve, the code checked whether the observer was close enough to the umbral shadow to bother:
if (mMax < Math.abs(L2max) * 1.5) {
tC2 = solveContact(...)
tC3 = solveContact(...)
}
The * 1.5 factor
was meant to be a generous guard. But L2 (the umbral
radius) is typically around 0.005 fundamental-plane units. Multiplying by 1.5 gives a threshold of
0.0075 FP units — roughly 57 km beyond the actual path edge.
Any observer within 57 km of the path limit would have the solver attempt to find C2 and C3. Newton-Raphson is a root finder; given certain starting conditions, it can find a solution even when none exists physically. The result: observers clearly outside the path would receive C2 and C3 times — a confident prediction of totality that would never happen.
The fix is to use a fixed offset that matches the actual source of imprecision — floating-point rounding in the geodetic-to-geocentric coordinate conversion — rather than a fraction of the umbral radius:
// 0.001 FP units ≈ 6 km — covers geodetic rounding noise
// without admitting observers meaningfully outside the path
if (mMax < Math.abs(L2max) + 0.001) {
tC2 = solveContact(...)
tC3 = solveContact(...)
} Why a fixed offset, not a relative one? The rounding error
in coordinate conversion is an absolute quantity bounded by a few kilometers — not a fraction of the
umbral radius. A relative margin like * 1.001
would be too small for narrow umbral cones and too large for wide ones. The 0.001 FP units
(~ 6 km) fixed offset is the right shape for the error it guards against.
Bug 2 — Limb Corrections Capped Too Tightly for Graze-Zone Observers
Once smooth-limb contact times are solved, eclipseClick optionally applies lunar limb corrections. The Moon's silhouette is not a perfect circle — mountains and valleys shift the precise moment totality begins and ends. The correction converts a topographic deviation (in arcseconds) into a time offset using the shadow's angular velocity at that contact.
The correction engine had a hard cap:
const MAX_CORRECTION_HOURS = 0.005 // 18 seconds For observers in the middle of the path, 18 seconds is generous. Published limb corrections for interior locations rarely exceed 5–10 seconds. But the physics is different at the path edge.
When mmax nearly equals L2, the shadow grazes the observer. At these locations the shadow velocity has a very shallow component along the limb — the same topographic feature that produces a 1-second correction for an interior observer can produce a 30–80 second correction for an observer at the path limit. The Explanatory Supplement to the Astronomical Ephemeris notes this explicitly for path-edge eclipse predictions.
With the 18-second cap, these large but physically legitimate corrections were silently discarded. Graze-zone observers saw uncorrected smooth-limb contact times — the least accurate result for exactly the locations where accuracy matters most.
// 90s ≈ 3× the maximum physically expected graze-zone correction
// Rejects runaway corrections from DEM artifacts or instability
const MAX_CORRECTION_HOURS = 0.025 // 90 seconds
// Allow one extra iteration for graze-zone convergence
const MAX_LIMB_ITERATIONS = 3 The 90-second ceiling is about 3× the worst-case graze-zone correction documented in the literature (~30 seconds), giving enough room for real physics while still rejecting numerical runaway from DEM noise or edge-case instability.
Why These Two Bugs Compound
The bugs were independent in their causes but interacted badly in practice. Consider an observer 30 km outside the path limit:
| Scenario | Bug 1 | Bug 2 | Result |
|---|---|---|---|
| 30 km outside path | Gate passes (57 km margin) | Cap clips corrections | False C2/C3 returned |
| 30 km inside path (graze) | Gate passes correctly | 40–60s correction dropped | Uncorrected times returned |
| After both fixes | 6 km margin only | 90s cap accepts all real corrections | Correct result in both cases |
What This Means for 2026
The August 12, 2026 total solar eclipse crosses Iceland, the Faroe Islands, and northern Spain before exiting over the Mediterranean. Graze-zone locations — where totality lasts only a few seconds to a minute — are some of the most sought-after observing sites precisely because the eclipse geometry is most interesting there. The diamond ring is longest, Baily's beads are most prominent, and the shadow edge passes directly overhead.
These are exactly the locations where eclipseClick was computing incorrect contact times. With both fixes applied, graze-zone observers now receive:
- Null C2/C3 when they are outside the path — no false totality predictions.
- Corrected C2/C3 with realistic limb corrections when inside the path — including the large corrections that the old 18-second cap was silently discarding.
- Null limb corrections when the arc-integration algorithm determines no valley in the search window produces a crossing — the totality window is closed entirely for some locations very close to the mathematical path edge.
The test suite now enforces this as an invariant: whenever smooth-limb C2/C3 exist, limb corrections must also be non-null. Twelve graze-zone locations from Iceland's southern coast to northern Spain's Picos de Europa are covered.
Context: A Larger Limb Correction Overhaul
These two fixes are part of a broader overhaul of the limb correction engine.
Earlier work fixed four bugs that were producing corrections 25× too large — including
an inverted C2 sign, a 46° error in the position angle formula, and accumulated rounding
inside an asin() call. After all
those repairs, C2 predictions match Eclipse Orchestrator within 0.2 seconds for the 2026
eclipse at the Spain test location.
A Note on the Math
The corrected guard condition deserves one more note. The
Math.abs()
around L2max
handles a sign convention: L2 is positive for
total eclipses and negative for annular eclipses (where the umbral cone converges
before reaching Earth). For the total eclipses eclipseClick targets, it's a no-op — but it
makes the guard correct by construction for any eclipse type.
The + 0.001
additive form is equally intentional. The rounding error in geodetic-to-geocentric conversion is
an absolute quantity — not a fraction of the umbral radius. A relative margin would be
too small for narrow umbral cones and too large for wide ones. The fixed offset is the right
shape for the error it guards against.
Taken together, the two fixes ensure that eclipseClick's most complex predictions — graze-zone contact times with full lunar limb corrections — are accurate for exactly the observers who need them most: the ones who drove to the edge of the shadow to experience a few seconds of totality.
Planning a graze-zone observation?
eclipseClick computes contact times and limb corrections for any location along the 2026 eclipse path.