fix(api): backfill non-array test_account_filters rows#58375
Conversation
|
🎭 Playwright didn't run on this PR — your changes touch code that could affect E2E behavior, but Playwright is opt-in via label now to keep CI cost down. Add the Most PRs don't need this. Real regressions still get caught on master and fix-forward. |
Migration SQL ChangesHey 👋, we've detected some migrations on this PR. Here's the SQL output for each migration, make sure they make sense:
|
🔍 Migration Risk AnalysisWe've analyzed your migrations for potential risks. Summary: 0 Safe | 1 Needs Review | 0 Blocked
|
|
Size Change: +21.4 kB (+0.02%) Total Size: 117 MB 📦 View Changed
ℹ️ View Unchanged
|
|
This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, please remove the |
|
issue reported by a customer here: https://posthoghelp.zendesk.com/agent/tickets/58670 |
|
5c6f93b to
aa61bae
Compare
Merge activity
|
thmsobrmlr
left a comment
There was a problem hiding this comment.
Hmm, I had migrated all faulty ones by hand.. wonder how these slipped in?
|
@thmsobrmlr what did you run? i checked these two queries SELECT
jsonb_typeof(test_account_filters) AS taf_type,
COUNT(*) AS team_count
FROM posthog_team
WHERE jsonb_typeof(test_account_filters) IS DISTINCT FROM 'array'
GROUP BY 1
ORDER BY team_count DESC;SELECT
t.id AS team_id,
o.id AS organization_id,
o.name AS organization_name,
t.name AS team_name,
jsonb_typeof(t.test_account_filters) AS taf_type,
-- Preview what the migration will write:
-- string parseable as JSON array → keeps parsed contents
-- anything else (object, number, bool, JSON null) → []
CASE
WHEN jsonb_typeof(t.test_account_filters) = 'string'
AND jsonb_typeof((t.test_account_filters #>> '{}')::jsonb) = 'array'
THEN (t.test_account_filters #>> '{}')::jsonb
ELSE '[]'::jsonb
END AS will_become,
t.test_account_filters AS current_value
FROM posthog_team t
JOIN posthog_organization o ON o.id = t.organization_id
WHERE jsonb_typeof(t.test_account_filters) IS DISTINCT FROM 'array'
ORDER BY t.id
LIMIT 100; |
Query snapshots: Backend query snapshots updatedChanges: 1 snapshots (1 modified, 0 added, 0 deleted) What this means:
Next steps:
|
1e20aef to
5b30e47
Compare
5b30e47 to
8fd943c
Compare

Problem
Team.test_account_filtersis a free-formjsonb, but every consumer expects an array of property filters. Before request-time validation shipped (#58129 + #58320), some rows ended up as JSON strings (most commonly fromproject-settings-updateMCP). Those rows still need cleaning. Prod-us currently has 21 affected teams.Changes
Data migration
1179_fix_non_list_test_account_filters: filters withjsonb_typeof != 'array', keeps the parsed list if the value is a stringified array, else[]. Batchedbulk_update,reverse_code=noop, ActivityLog retains the prior value.How did you test this code?
Agent-PR. Verified locally by seeding 4 bad shapes (stringified-array / non-array / object / json-null) and running
manage.py migrate posthog 1179— all converged correctly, parsed array preserved. Unit test added atposthog/test/test_migration_1179.py(mark-skipped per repo convention for migration tests).Reviewer / on-call: run on prod before merge —
Publish to changelog?
No.
🤖 Agent context
Originally a 6-commit PR adding validator + frontend defenses + this migration. While the PR sat open, #58129/#58320 shipped the validator, making 5 of 6 commits redundant. Trimmed to just the migration. Session: https://claude.ai/code/session_0138DNFGspPWbFhEC6p9F5AV