---
title: generate-nfl-team-seasonlogs writes nothing and exits 0
type: task
status: planned
description: >-
  scripts/generate-nfl-team-seasonlogs.mjs fails its insert on every run with a NOT NULL violation
  on nfl_team, and exits 0 regardless because main() catches the throw. The team rollup table is
  therefore stale with no indication. Pre-existing: reproduced by control run at 3c7df0e22.
base_uri: user:task/league/fix-generate-nfl-team-seasonlogs-null-team-insert.md
created_at: '2026-08-05T20:32:55.940Z'
entity_id: 893b59f8-7bb4-44d5-894e-7df19f82551e
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: High
public_read: true
tags:
  - user:tag/league-xo-football.md
updated_at: '2026-09-02T15:48:11.046Z'
visibility_analyzed_at: '2026-11-05T23:49:24.261Z'
---

# generate-nfl-team-seasonlogs writes nothing and exits 0

`scripts/generate-nfl-team-seasonlogs.mjs` fails its insert on every run:

```
null value in column "nfl_team" of relation "nfl_team_seasonlogs" violates not-null constraint
```

**It exits 0 anyway.** `main()` catches the throw, logs it through `debug`, and exits cleanly — so no exit-code oracle, no cron alert and no signal can see it. That is the same shape as the `generate-player-snaps` defect documented in the league `CLAUDE.md`, and it is why this went unnoticed.

Found 2026-08-05 while confirming that two new `all_fantasy_stats` members did not break the rollup. They did not — the failure is on `nfl_team`, and a control run at `3c7df0e22` (before the SFB16 work) reproduces it identically.

## What is known

- The run loads 34,962 gamelogs for 2024 REG and builds 960 team-stat rows before failing.
- No `player_gamelogs` row for 2024 REG has a null `nfl_team`, so the null is introduced by the rollup itself rather than inherited from its input.
- 960 rows for 18 weeks and 32 teams is not `32 * 18`; the row set spans several stat groupings, and identifying which grouping emits a team-less row is the first step.

## Why it matters

`nfl_team_seasonlogs` is the team-level rollup of every `all_fantasy_stats` member. While this is broken the table is stale, and anything reading team season stats is reading whatever was last successfully written — with no indication of age.

## Plan

- [ ] **Find the grouping that emits a row with no team**
  - The 960 constructed rows are in memory before the insert; dump the ones whose `nfl_team` is null and read what produced them.

- [ ] **Fix the cause, not the symptom**
  - Filtering out the null-team rows would make the script exit 0 having silently dropped real data. Establish what those rows are meant to represent first.

- [ ] **Make the failure visible**
  - The script must exit non-zero, or raise a signal, when its insert fails. Follow [[user:guideline/surface-pipeline-failures.md]] — an output oracle distinct from the exit code.

- [ ] **Confirm with a real run**
  - Verify: the script writes rows for 2024 REG and the row count is what the grouping predicts, not merely that it stopped throwing.
