Fix double URL-encoding of context param in remote feature flags#177
Closed
corleymj wants to merge 1 commit into
Closed
Fix double URL-encoding of context param in remote feature flags#177corleymj wants to merge 1 commit into
corleymj wants to merge 1 commit into
Conversation
The `_prepare_query_params` method was manually URL-encoding the JSON
context string via `urllib.parse.quote()` before passing it as an httpx
query parameter. Since httpx also URL-encodes all query parameter values,
the context was double-encoded — e.g. `{` became `%257B` instead of
`%7B` — causing the Mixpanel `/flags` API to return 400 Bad Request.
The fix passes the raw JSON string directly and lets httpx handle the
single layer of URL encoding as intended.
Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
|
Nice I found the same issue in #175 |
lajohn4747
added a commit
that referenced
this pull request
Jun 13, 2026
efahk
approved these changes
Jun 15, 2026
tylerjroach
approved these changes
Jun 15, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #177 +/- ##
==========================================
+ Coverage 94.50% 94.58% +0.07%
==========================================
Files 12 12
Lines 1947 1975 +28
Branches 116 116
==========================================
+ Hits 1840 1868 +28
Misses 70 70
Partials 37 37
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
lajohn4747
added a commit
that referenced
this pull request
Jun 17, 2026
* Add Service Account support * Fix lint * refactor: use generic credentials parameter with type alias - Rename service_account parameter to credentials for extensibility - Add MixpanelCredentials type alias (Union[ServiceAccountCredentials]) - Keep ServiceAccountCredentials as standalone class (no base class) - Update Mixpanel, Consumer, and BufferedConsumer signatures - Update all tests, README, and CHANGELOG Benefits: - Generic parameter name supports future credential types - Type alias is single source of truth for supported types - Easy to extend: just add to Union when adding OAuth, API keys, etc. - Self-documenting via IDE type hints * refactor: move credentials to separate module - Create mixpanel/credentials.py for authentication classes - Move ServiceAccountCredentials and MixpanelCredentials to new file - Import from credentials module in __init__.py - Improves code organization and separation of concerns Benefits: - Cleaner module structure - Easier to add new credential types in one place - Credentials logic isolated from core tracking code * feat: add APISecretCredentials class - Add APISecretCredentials for API secret authentication - Mark as deprecated in favor of ServiceAccountCredentials - Update MixpanelCredentials type alias to Union of both types - Add 4 new tests for API secret credentials Benefits: - Consistent credentials pattern for all auth types - Explicit deprecation path from API secrets to service accounts - Type-safe: validation at construction time - All auth methods now use credentials classes * Clean up by hannd * Clean up * Pass creds into feature flags * Use httpx for flags * Update to avoid credentials for custom consumers and flags * Fix consumer * Update * Fix changelog * Add comments * Update change log * Remove credentials * Fix readme * Use credentials for feature flag and fix encoding * Ensure we don't fallback on token * Update tests * Don't need api_key * Update deprecation methods * Add logging to api_key too * Comments handled * Handle Greptile comments * Update comment * Fix greptile nits * Remove imports * Clean up readme and tests * Pass credentials into Consumer * Update documentation * Clear up tests * Add warnings * Fix comments * remove dead var * Fix lint * Fix lint * Handle lint errros * add the encoding tests from PR #177 * Keep project token for flags --------- Co-authored-by: John La <10409759+lajohn4747@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RemoteFeatureFlagsProvider._prepare_query_paramsmanually URL-encodes the JSON context string viaurllib.parse.quote()before passing it as an httpx query parameter. Since httpx also URL-encodes all query parameter values when constructing the request URL, thecontextparameter ends up double-encoded:{%7B%257B"%22%2522:%3A%253AThis causes the Mixpanel
/flagsAPI to return 400 Bad Request because it cannot parse the garbled context.Before (broken)
After (fixed)
Changes
mixpanel/flags/remote_feature_flags.py: Remove manualurllib.parse.quote()and.encode("utf-8")in_prepare_query_params. Pass the raw JSON string and let httpx handle URL encoding.mixpanel/flags/test_remote_feature_flags.py: AddTestPrepareQueryParamstest class covering:str, notbytesflag_keypresence/absenceTest plan
pytest mixpanel/flags/test_remote_feature_flags.py)test_request_url_has_properly_encoded_contextasserts no%257B(double-encode) orb%27(bytes literal) in the outgoing URL/flagsAPI — 400s resolve with this fix appliedMade with Cursor