Skip to content
14 changes: 14 additions & 0 deletions .changeset/unresolved-local-flags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"posthog-php": minor
---

Report the flags local evaluation could not resolve on `evaluateFlags()` snapshots. `FeatureFlagEvaluations::getUnresolvedFlags()` maps each such flag key to an `UnresolvedFlagReason` value: `experience_continuity`, `unsupported_definition`, `unresolved_dependency` or `missing_context`.

Behavior changes:

- A condition with a filter that local evaluation cannot check and a filter that does not match now resolves locally as no match. An inconclusive flag dependency in one condition no longer stops a later condition from resolving the flag. So a flag that went to the server before can now resolve locally. A dependency that needs server data, such as a static cohort, still sends the flag to the server.
- An inactive flag with experience continuity enabled now resolves to `false` locally instead of going to the server.
- A flag that depends on a flag with experience continuity enabled no longer resolves locally. It goes to the server, or stays unresolved with `onlyEvaluateLocally`.
- A malformed date in a flag filter or a person property now makes its condition inconclusive, like other malformed values, instead of failing local evaluation of the whole flag.
- `$feature_flag_called` events from snapshot reads of unresolved flags report `local_evaluation_inconclusive` instead of `flag_missing`.
- When a fresh flag definitions response (HTTP 200) loads, the SDK logs a warning, also with `debug` off, that names the flags local evaluation can never resolve: flags with experience continuity, and flags that use a static cohort, an unknown operator, a malformed value, or a missing or circular dependency. Each flag is warned about once per client until its definition changes. Definitions from a cache provider or a 304 response do not log the warning. Without a `flag_definition_cache_provider`, each new client fetches fresh definitions, so under PHP-FPM the warning is logged on every request. Configure a cache provider to log it only when definitions are fetched.
207 changes: 207 additions & 0 deletions api/public-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,54 @@
}
]
},
"getDefinitionUnresolvedReason": {
"static": true,
"abstract": false,
"final": false,
"returnType": "?string",
"parameters": [
{
"name": "flag",
"type": null,
"byReference": false,
"variadic": false,
"optional": false,
"default": null,
"defaultConstant": null,
"hasDefault": false
},
{
"name": "flagsByKey",
"type": null,
"byReference": false,
"variadic": false,
"optional": false,
"default": null,
"defaultConstant": null,
"hasDefault": false
},
{
"name": "cohorts",
"type": null,
"byReference": false,
"variadic": false,
"optional": false,
"default": null,
"defaultConstant": null,
"hasDefault": false
},
{
"name": "groupTypeMapping",
"type": null,
"byReference": false,
"variadic": false,
"optional": false,
"default": null,
"defaultConstant": null,
"hasDefault": false
}
]
},
"matchCohort": {
"static": true,
"abstract": false,
Expand Down Expand Up @@ -2554,6 +2602,10 @@
"type": "string",
"value": "flag_missing"
},
"LOCAL_EVALUATION_INCONCLUSIVE": {
"type": "string",
"value": "local_evaluation_inconclusive"
},
"QUOTA_LIMITED": {
"type": "string",
"value": "quota_limited"
Expand Down Expand Up @@ -2704,6 +2756,16 @@
"default": null,
"defaultConstant": null,
"hasDefault": true
},
{
"name": "unresolvedFlags",
"type": "array",
"byReference": false,
"variadic": false,
"optional": true,
"default": [],
"defaultConstant": null,
"hasDefault": true
}
]
},
Expand Down Expand Up @@ -2757,6 +2819,13 @@
"returnType": "array",
"parameters": []
},
"getUnresolvedFlags": {
"static": false,
"abstract": false,
"final": false,
"returnType": "array",
"parameters": []
},
"isEnabled": {
"static": false,
"abstract": false,
Expand Down Expand Up @@ -3405,12 +3474,67 @@
"constants": [],
"properties": [],
"methods": {
"__construct": {
"static": false,
"abstract": false,
"final": false,
"returnType": null,
"parameters": [
{
"name": "message",
"type": "string",
"byReference": false,
"variadic": false,
"optional": true,
"default": "",
"defaultConstant": null,
"hasDefault": true
},
{
"name": "code",
"type": "int",
"byReference": false,
"variadic": false,
"optional": true,
"default": 0,
"defaultConstant": null,
"hasDefault": true
},
{
"name": "previous",
"type": "?Throwable",
"byReference": false,
"variadic": false,
"optional": true,
"default": null,
"defaultConstant": null,
"hasDefault": true
},
{
"name": "reason",
"type": "string",
"byReference": false,
"variadic": false,
"optional": true,
"default": "unsupported_definition",
"defaultConstant": "PostHog\\UnresolvedFlagReason::UNSUPPORTED_DEFINITION",
"hasDefault": true
}
]
},
"errorMessage": {
"static": false,
"abstract": false,
"final": false,
"returnType": null,
"parameters": []
},
"getReason": {
"static": false,
"abstract": false,
"final": false,
"returnType": "string",
"parameters": []
}
}
},
Expand Down Expand Up @@ -4571,12 +4695,67 @@
"constants": [],
"properties": [],
"methods": {
"__construct": {
"static": false,
"abstract": false,
"final": false,
"returnType": null,
"parameters": [
{
"name": "message",
"type": "string",
"byReference": false,
"variadic": false,
"optional": true,
"default": "",
"defaultConstant": null,
"hasDefault": true
},
{
"name": "code",
"type": "int",
"byReference": false,
"variadic": false,
"optional": true,
"default": 0,
"defaultConstant": null,
"hasDefault": true
},
{
"name": "previous",
"type": "?Throwable",
"byReference": false,
"variadic": false,
"optional": true,
"default": null,
"defaultConstant": null,
"hasDefault": true
},
{
"name": "reason",
"type": "string",
"byReference": false,
"variadic": false,
"optional": true,
"default": "unsupported_definition",
"defaultConstant": "PostHog\\UnresolvedFlagReason::UNSUPPORTED_DEFINITION",
"hasDefault": true
}
]
},
"errorMessage": {
"static": false,
"abstract": false,
"final": false,
"returnType": null,
"parameters": []
},
"getReason": {
"static": false,
"abstract": false,
"final": false,
"returnType": "string",
"parameters": []
}
}
},
Expand Down Expand Up @@ -4726,6 +4905,34 @@
}
}
},
"PostHog\\UnresolvedFlagReason": {
"type": "class",
"abstract": false,
"final": false,
"readonly": false,
"extends": null,
"implements": [],
"constants": {
"EXPERIENCE_CONTINUITY": {
"type": "string",
"value": "experience_continuity"
},
"MISSING_CONTEXT": {
"type": "string",
"value": "missing_context"
},
"UNRESOLVED_DEPENDENCY": {
"type": "string",
"value": "unresolved_dependency"
},
"UNSUPPORTED_DEFINITION": {
"type": "string",
"value": "unsupported_definition"
}
},
"properties": [],
"methods": []
},
"PostHog\\Uuid": {
"type": "class",
"abstract": false,
Expand Down
Loading
Loading