SPC outlook issue time has never parsed: issued_at is NULL on every row, and "issued" times shown are the fetch time #201
Labels
No labels
area:ai
area:ci-cd
area:notifications
area:observability
area:public-pages
backlog
bug
duplicate
enhancement
help wanted
invalid
question
security
type:decision
type:feature
type:infra
type:maintenance
type:security
v1.0.1
v1.1.0
v1.2.0
v1.3.0
v2.0.0
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/WeatherBot#201
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found 2026-10-13 while checking dev's logs before resuming the v2.0.0 soak. Not a regression in the release candidates: the parser dates from the original SPC commit (
e4b8297).Symptom
Dev (
2.0.0-rc4) logged, in the last 24 hours:And in dev's database,
spc_outlook_pages: 194 rows, 0 withissued_at, spanning 2026-06-24 to 2026-10-13.Cause
NOAA's MapServer returns the issue time as a compact 12-digit string. Live sample from
SPC_wx_outlks/MapServer/1today:spc._parse_datetime(app/services/spc.py:107) only triesdatetime.fromisoformat, which rejects that shape:So
_parse_convective_feature, the fire parser (valid) and the extended parser all getNone.The existing test fixture already uses the real format (
"issue": "202604161630"intests/test_spc_correctness.py:257) but nothing asserts on the parsed value, so it passes.Effect
Every consumer falls back, mostly to "now":
app/api/alerts.py:301,320,343:outlook.issued_at or datetime.now(...). The dashboard's SPC "issued" time is the time of the request, not of the outlook.app/services/spc_impacts.py:66: the impact window base is the fetch time.app/services/radar.py:504: the SPC GIF's valid date is skipped.app/api/public.py:362,app/api/spc_impacts.py:255:issued_utcrenders empty.app/services/ai_context.py:322: the AI summary context carries no issue time.Alert delivery is not affected. Dedup uses
product_id, which is built from the raw string.Fix
_parse_datetimethe%Y%m%d%H%Mform (UTC).product_idembeds the raw issue string (D1_202610131252), so it is recoverable for convective outlooks.Not a v2.0.0 blocker on its own, but the Explorer's day view shows SPC risk bands (#138), so wrong SPC timestamps are visible in the headline feature.
The one-line parser fix is not safe on its own for fire outlooks
Started the fix and stopped before committing, because populating
issued_atwakes up code that has never run with a real value.spc_outlook_expires(app/services/spc_impacts.py:66) computes expiry asissued_atat 0800Z plusdaydays. Todayissued_atis always NULL, so the base is "now", which is within hours of the real issue time. That is why the result has been roughly right by accident.issue. Parsing it gives the same expiry as today, minus the drift around 00Z. Safe.issuefield at all. The fire layers expose onlyvalid,expire,idp_filedate,idp_ingestdate,idp_source, and_parse_fire_featurepassesvalidas the issue time. For a Day 2 fire outlookvalidis tomorrow 1200Z, so once it parses, expiry becomes tomorrow + 2 days: one day later than now. A Day 2 Critical/Extreme fire record would stay active on the dashboard a day too long._spc_valid_date(app/services/radar.py:498) has the same shape (issued_at + day) and would shift the Day 2 fire map date the same way.Options for fire
idp_filedate(epoch ms;_parse_datetimealready handles numbers) as the issue time. Sample today: file date 07:45Z for the 1200Z-valid Day 1 product, so it is a close proxy for issuance.expirefield NOAA already sends on every feature, for all three product families. More correct, larger change, and it alters when existing records clear.Leaning 1 for a contained fix, with 2 as a follow-up. Needs a decision before any code lands, since both change alert-record lifetimes.
Confirmed on production (1.8.1), 2026-10-13:
spc_outlook_pageshas 75 rows, 0 withissued_at, and the same warning fired 1,933 times in the last 24 hours (902 / 567 / 464 for days 2 / 3 / 1). Identical to dev, so this is not specific to the release candidates.Decision (@rbrooks, 2026-10-13): option 1 now, option 2 later if needed. Implemented in #202 (
af7ee6e), awaiting review and merge.Correction to my earlier comment: the fire feed's file time on 2026-10-13 is 05:45Z, not 07:45Z (I mis-converted the epoch value). It is still within minutes of issuance, so the reasoning for option 1 stands; #202 and its tests use the correct value.
Leaving this open until #202 is merged. Existing rows are not backfilled by #202.
Merged via #202 (
af7ee6e). CI run 243 green in 7m23s, both test tiers.Closing as fixed on
main. Not yet released: it ships in the next release candidate, and the first real confirmation isissued_atpopulating on newspc_outlook_pagesrows on dev, with the "missing parseable issue time" warning gone from the log.Not done, by choice: existing rows are not backfilled, and option 2 (take expiry from NOAA's
expirefield) is deferred. Open a new issue for either if wanted.