Repository navigation
Conversation
A secret key without the Feature flags: Read scope gets 401 from /flags/definitions on every poll, so the client logged an error every 30 seconds. Log one warning for 401 and 403 that names the scope and enable_local_evaluation=False, and again only after definitions load. Polling, state clearing on 401 and debug-mode raising stay as they were. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Note 🤖 Claude Opus 5.5 responding on behalf of Michael Decisions made while building this fix:
|
posthog-python Compliance ReportDate: 2026-11-05T12:14:49.489922+00:00 ✅ All Tests Passed!121/121 tests passed Capture_V1 Tests✅ 95/95 tests passed View Details
Capture_Ai Tests✅ 5/5 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
Feature_Flags_Local_Evaluation Tests✅ 4/4 tests passed View Details
|
SDK performance: posthog-pythonBenchmarks completed. No changes flagged for review. Flags require at least a 5% change in the median and all six pairs agreeing on direction. This is a noise filter, not proof of a performance change or a CI gate. View all results
Values are medians of paired measurements. Not flagged does not mean unchanged. Unavailable means a measurement could not be provided, not zero. Estimated allocation measurements retain their instrumentation uncertainty. RSS measures the whole process, not just SDK allocations; observed peaks are sampled checkpoints. Paired ranges in the diagnostics describe variability, not confidence intervals. Each shard uses its own runner; compare Before PR against With PR within a row, not across shards. Compared 102 metric rows; 102 rows shown in all results. Omitted or shortened data remain in |
💡 Motivation and Context
When you pass a
secret_key, the client turns on local evaluation and polls/flags/definitionsevery 30 seconds. Transactional email asks for a Project Secret API Key with only thetransactional_email:writescope. The flags service answers that key with401 authentication_failed("Secret API token is invalid."), the same answer as a wrong key, because its key lookup only finds keys with a flag scope. A personal API key without the scope gets403 permission_denied.So a client that only sends email logged an ERROR about feature flags every 30 seconds, for as long as it ran. 403 also logged an ERROR on every poll.
Merge Danger
Low, two-way door. Only the log level and frequency for 401 and 403 from
/flags/definitionschange. Polling, flag state (401 still clears definitions), debug-mode raising and remote evaluation are unchanged.What changes
enable_local_evaluation=Falseturns local evaluation off.This PR is independent of the email PR #1171. Both touch
posthog/client.py, but in different places, and this diff applies cleanly on that PR's head.💚 How did you test it?
posthog/test/test_feature_flags.py: five polls answered with 401 or 403 log one WARNING (it was five ERRORs before the fix), and a 200 between rejections warns again. They failed before the fix and pass now.test_load_feature_flags_unauthorizedandtest_load_feature_flags_wrong_keynow expect the WARNING.pytest posthog/test/: 6096 passed, 25 skipped.ruff format --check,ruff check,mypy | mypy-baseline filterandpython -W error -c "import posthog"pass.Client._load_feature_flagswithposthog.client.getmocked to raiseAPIError.Posthogclient withsecret_keyandpoll_interval=1polled a local stub of/flags/definitionsthat sends the flags service's 401 and 403 bodies. Over 9 polls (three 401s, a 200, then 401s) it logged two WARNINGs, one before and one after the load. Five 403s logged one. The same run onmainlogged 8 ERRORs.rust/feature-flags/src/api/auth.rsanderrors.rsin PostHog/posthog.📝 Checklist
If releasing new changes
sampo addto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Claude Code (Claude Opus 5.5) wrote the change test-first in a T3 Code thread, as a side fix from the transactional email work. GPT-6.1 Sol reviewed the diff before the push and found nothing that holds. The same fix is going to posthog-node, posthog-go, posthog-php and posthog-elixir.
posthoglogger, then DEBUGInvolvement: one cross-family review (GPT-6.1 Sol), no grilling rounds, live-run proof against a local stub of the flags service.
🤖 Generated with Claude Code