Skip to content

Commit 3dc4f93

Browse files
authored
fix: handle NULL status values in migration 008 (#578)
## Problem Production deployment is failing with CrashLoopBackOff. Migration 008 fails with: ``` ERROR: column "status" of relation "servers" contains null values (SQLSTATE 23502) ``` ## Root Cause The migration extracts the `status` field from an unexpected location in the data structure. ### Actual Data Structure (Before Migration) In the current format, `status` is at the **top level** of the JSON, not nested in official metadata: ```json { "name": "com.example/server", "version": "1.0.0", "status": "active", ← STATUS IS HERE (top level) "_meta": { "io.modelcontextprotocol.registry/official": { "serverId": "uuid", "publishedAt": "2025-09-01T00:00:00Z", "isLatest": true // NO STATUS FIELD HERE } } } ``` For 120 out of 765 servers, the status field is **missing entirely**: ```json { "name": "com.biodnd/agent-ip", "version": "0.1.2", // ← NO STATUS FIELD AT ALL "_meta": { "io.modelcontextprotocol.registry/official": { "serverId": "uuid", "publishedAt": "2025-09-23T09:47:07Z", "isLatest": true // STILL NO STATUS FIELD HERE } } } ``` ### Original Migration Logic ```sql IF official_meta IS NOT NULL THEN UPDATE servers SET status = (official_meta->>'status'), -- Extracts NULL for all servers ``` **Result:** - All 765 servers would have NULL status extracted - Because `official_meta->>'status'` returns NULL (field doesn't exist there) - The migration tries to add `NOT NULL` constraint → fails ### Fixed Migration Logic ```sql IF official_meta IS NOT NULL THEN UPDATE servers SET status = COALESCE(NULLIF(rec.value->>'status', 'null'), 'active'), ``` **Result:** - Extracts from top-level JSON where status actually exists - `NULLIF(rec.value->>'status', 'null')` handles edge case of literal string "null" - `COALESCE(..., 'active')` provides fallback when status is missing - All servers get valid status value ### Impact Breakdown **645 servers with `"status": "active"`:** - Before fix: Would extract NULL → migration fails - After fix: Extracts "active" correctly **120 servers with missing status field:** - Before fix: Would extract NULL → migration fails - After fix: Defaults to 'active' via COALESCE ## Example Servers with Missing Status (First 9 discovered during investigation) - com.biodnd/agent-ip - io.github.jkakar/cookwith-mcp - com.joelverhagen.mcp/Knapcode.SampleMcpServer - io.github.Lyellr88/marm-mcp-server - com.biodnd/agent-press - io.github.timheuer/sampledotnetmcpserver - io.github.CodeCraftersLLC/local-voice-mcp - com.biodnd/agent-fin - io.github.ruvnet/ruv-swarm ## Testing Verified against production data (765 total servers): - ✅ All servers have official metadata - ✅ None have status in official metadata (expected) - ✅ 645 have "status": "active" at top level - ✅ 120 have missing status field (no field present) - ✅ Fix extracts from correct location for all cases ## Impact This unblocks production deployment. Once merged and released as v1.2.1, the migration will: 1. Extract status from the correct location (top-level JSON) 2. Handle missing status fields with sensible defaults 3. Successfully add NOT NULL constraint 4. Allow pods to start normally --- 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent bef665a commit 3dc4f93

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

internal/database/migrations/008_separate_official_metadata.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ BEGIN
3535

3636
IF official_meta IS NOT NULL THEN
3737
-- Update columns with extracted metadata
38+
-- Note: status is at top level in old format, not in official_meta
3839
UPDATE servers
3940
SET
40-
status = (official_meta->>'status')::VARCHAR(50),
41+
status = COALESCE(NULLIF(rec.value->>'status', 'null'), 'active'),
4142
published_at = (official_meta->>'publishedAt')::TIMESTAMP WITH TIME ZONE,
4243
updated_at = (official_meta->>'updatedAt')::TIMESTAMP WITH TIME ZONE,
4344
is_latest = (official_meta->>'isLatest')::BOOLEAN
@@ -46,7 +47,7 @@ BEGIN
4647
-- Handle records without official metadata (set defaults)
4748
UPDATE servers
4849
SET
49-
status = COALESCE((rec.value->>'status'), 'active'),
50+
status = COALESCE(NULLIF(rec.value->>'status', 'null'), 'active'),
5051
published_at = NOW(),
5152
updated_at = NOW(),
5253
is_latest = true

0 commit comments

Comments
 (0)