Skip to content

Conversation

@igormq
Copy link
Contributor

@igormq igormq commented Jan 21, 2026

Summary

  • Propagate personProperties and groups to captureStateless when $feature_flag_called events are sent during feature flag evaluation
  • Log HTTP request and response headers in debug mode for easier troubleshooting
  • Add evaluationContexts support to server module's PostHogConfig (was missing and not propagated to core config)
  • Add $lib and $lib_version to /flags API requests for SDK identification
  • Workaround: Use posthog-java/server User-Agent for server-side runtime detection (PostHog doesn't recognize posthog-server/ yet)

Details

Feature Flag Event Context

When getFeatureFlagStateless calls captureStateless for the $feature_flag_called event, the personProperties and groups are now propagated to provide full context.

Debug Header Logging

When debug=true, request headers are logged before sending and response headers + final request headers (after interceptors like gzip) are logged after receiving the response.

Server-side Runtime Detection

PostHog uses User-Agent patterns to detect server-side vs client-side SDKs. The recognized patterns include posthog-java/, posthog-python/, etc., but not posthog-server/.

As a workaround, the server SDK now uses posthog-java/server/{version} as the User-Agent, which matches PostHog's detection patterns and allows server-only feature flags to be returned correctly.

The userAgent property in PostHogConfig is now configurable, falling back to {sdkName}/{sdkVersion} if not explicitly set.

…g request headers in debug mode

This change addresses two issues:

1. When `getFeatureFlagStateless` calls `captureStateless` for the `$feature_flag_called` event,
   it now propagates the `personProperties` (as userProperties) and `groups` to the event.
   Previously these properties were available but not passed through, meaning the feature
   flag evaluation context was lost in the captured event.

2. In debug mode, the HTTP API now logs all request headers that are being sent. This helps
   developers troubleshoot issues by seeing exactly what headers are included in requests
   (User-Agent, Content-Type, Authorization, etc.).
@igormq igormq requested a review from a team as a code owner January 21, 2026 19:43
The server module's PostHogConfig was missing the evaluationContexts property
that exists in the core PostHogConfig. This meant that even when users set
evaluationContexts in their server config, it wasn't being propagated to the
core config and therefore wasn't sent in /flags API requests.

This change:
- Adds evaluationContexts property to server PostHogConfig constructor
- Propagates evaluationContexts to core config in asCoreConfig()
- Adds evaluationContexts() method to the Builder class
- Adds comprehensive tests for all the above
@marandaneto
Copy link
Member

@igormq is that #314 what you are trying to fix?
please merge main into your branch first since there are unrelated changes in your branch

@igormq
Copy link
Contributor Author

igormq commented Jan 21, 2026

@igormq is that #314 what you are trying to fix? please merge main into your branch first since there are unrelated changes in your branch

did not see this issue. trying to solving three problems:

  • the issue 314 (thanks for pointing out this)
  • the fact that i can't set any evaluation context
  • in debug mode we don't log all headers that we are setting (and somehow i am setting something in a hidden spring boot/libraries config that is sending as a client-side request).

@igormq
Copy link
Contributor Author

igormq commented Jan 21, 2026

Also @marandaneto I am seeing here that the library is setting the user agent to posthog-server, and due to that is not being identified as server runtime call.
In the docs:

https://posthog.com/docs/api/flags#runtime-detection

Runtime detection
Evaluation runtime (server vs. client) is automatically detected based on your request headers and user-agent. This determines which flags are available based on their runtime setting (server-only, client-only, or all).

How runtime is detected:

User-Agent patterns - The system analyzes the User-Agent header:

Client-side patterns: Mozilla/, Chrome/, Safari/, Firefox/, Edge/ (browsers), or mobile SDKs like posthog-android/, posthog-ios/, posthog-react-native/, posthog-flutter/
Server-side patterns: posthog-python/, posthog-ruby/, posthog-php/, posthog-java/, posthog-go/, posthog-node/, posthog-dotnet/, posthog-elixir/, python-requests/, curl/
Browser-specific headers - Presence of these headers indicates client-side:

Origin header
Referer header
Sec-Fetch-Mode header
Sec-Fetch-Site header
Default behavior - If runtime can't be determined, the system includes flags with no runtime requirement and those set to "all"

@igormq
Copy link
Contributor Author

igormq commented Jan 21, 2026

@marandaneto as workaround i will override the user agent for the server posthog config :)

…tion

Workaround: PostHog's runtime detection uses User-Agent patterns to determine
if requests come from server-side or client-side SDKs. The pattern
"posthog-server/" is not recognized, so we use "posthog-java/server/" instead
until PostHog adds support for "posthog-server/" in their detection patterns.

Also adds $lib and $lib_version to flags requests for SDK identification,
and makes userAgent configurable in PostHogConfig.
@igormq igormq force-pushed the chore/propagate-props-in-event branch from c7fde9d to 76e6f3c Compare January 21, 2026 20:40
igormq pushed a commit to igormq/posthog that referenced this pull request Jan 22, 2026
…K detection

This adds support for the `posthog-server/*` user agent pattern, allowing
client-side SDKs (like posthog-android, posthog-ios) running in server mode
to be properly detected as server-side runtime.

When a client SDK is used on the server (e.g., Android SDK in a backend
service), it can now send `posthog-server/{version}` as the user agent
to receive server-only feature flags.

Related: PostHog/posthog-android#382
@marandaneto
Copy link
Member

@igormq

the issue 314 (thanks for pointing out this)
the fact that i can't set any evaluation context
in debug mode we don't log all headers that we are setting (and somehow i am setting something in a hidden spring boot/libraries config that is sending as a client-side request).

lets address this in different PRs to make it easier
this PR should be just about #314

evaluation context has been added recently

- Renamed `evaluationEnvironments` to `evaluationContexts` for clearer semantics ([#368](https://github.com/PostHog/posthog-android/pull/368)). The term "contexts" better reflects that this feature is for specifying evaluation contexts (e.g., "web", "mobile", "checkout") rather than deployment environments (e.g., "staging", "production").

i think its just not exposed to server yet? @dustinbyrne

i dont think we should allow changing the userAgent, whats the use case?

lets split this up in 3 PRs

@igormq
Copy link
Contributor Author

igormq commented Jan 22, 2026

The user agent is just an workaround due to the problem in PostHog/posthog#45652
tldr: it is identifying the call as unknown (so if you have a flag only server side will never get the flag)

@marandaneto
Copy link
Member

The user agent is just an workaround due to the problem in PostHog/posthog#45652 tldr: it is identifying the call as unknown (so if you have a flag only server side will never get the flag)

again, this is another issue, another PR
lets split up
i think the SDK should set the user agent correctly, or the backend should consider posthog-server as valid, but i'd rather fix it instead of making a workaround

@igormq
Copy link
Contributor Author

igormq commented Jan 22, 2026

Closing this PR and splitting into 4 focused PRs as requested:

  1. feat: propagate personProperties and groups in feature flag events #383 - feat: propagate personProperties and groups in feature flag events
  2. feat: log HTTP request headers in debug mode #384 - feat: log HTTP request headers in debug mode
  3. feat: add evaluationContexts support to server PostHogConfig #385 - feat: add evaluationContexts support to server PostHogConfig
  4. fix: use posthog-java User-Agent for server-side runtime detection #386 - fix: use posthog-java/server User-Agent for server-side runtime detection

Each PR addresses a specific concern for easier review and merging.

@igormq igormq closed this Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants