You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chore(deps): update dependency flagsmith/sdk-spec to v0.7.0 - #105
To trigger a single review, invoke the @coderabbitai review command.
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Organization UI
Review profile: ASSERTIVE
Plan: Advanced
Run ID: 8398127c-f244-433c-9052-37da03b1036f
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
🔍 Trigger review
Walkthrough
The SDK specification workflow now uses version v0.6.0. New specification helpers support event-enabled clients, experiment flag retrieval, event tracking, and exposure tracking. Analytics timer callbacks now ignore the returned future after starting synchronisation. Experiment exposure events now include non-empty traits. Tests cover failed scheduled analytics requests and exposure events with traits.
Scheduled analytics send failures are now silent unless debug logging is enabled, and the new retry test can occasionally fail on a slow runner. Neither blocks merge, but both are worth addressing soon.
- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Spec v0.6.0 adds @events scenarios (getExperimentFlag, trackEvent, trackExposureEvent). The SDK already had event tracking, but CI failed on the missing Create the SDK client with events enabled step. Wiring the steps in exposed two gaps in the SDK.
Changes
fix: Keep the app running when scheduled flag analytics fail to send (36a294b). The flag analytics timer left a failed send's error unhandled, so any network failure or error response crashed the app. Under the spec, the runner deletes each scenario's project, so the previous client's next analytics flush got an error response and terminated the SDK process. Every later scenario then failed. The timer now drops the error, which syncAnalyticsData already logs, and the analytics are resent on the next tick. Direct calls to syncAnalyticsData() still throw as before. A regression test covers it and fails without the fix, with the same uncaught exception.
feat: Attach traits to exposures recorded by getExperimentFlag (b5f536a). The spec, and the Python reference SDK, expect the $flag_exposure from getExperimentFlag to carry the identity's traits. The Flutter SDK sent traits: null. Unit test added.
ci: Implement the event steps of SDK spec v0.6.0 (180ac98). sdk-spec/steps.dart maps the new steps to FlagsmithConfig(enableEvents: true, eventsURI: …), getExperimentFlag, trackEvent and trackExposureEvent. It only makes SDK calls.
Verification
flutter analyze: no issues. flutter test: 194 passed. The changed files are dart format clean.
Ran the v0.6.0 spec locally against the SDK image with MISSING_STEPS=fail. Before the fixes, 3 of 3 runs crashed. After them, 3 of 3 runs passed all 7 scenarios.
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔇 Additional comments: 1
lib/src/flagsmith_client.dart-433-433: 1
433-433: Major · Security & Privacy · Quick win
⚠️Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.
Exclude transient traits from exposure events.
A trait marked transient: true must not be persisted, but this map includes its value without the transient marker. The event processor sends that value to the events warehouse, where it is persisted. Exclude transient traits from the exposure payload. (flagsmith.com)
Review info
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Organization UI
Review profile: ASSERTIVE
Plan: Advanced
Run ID: 3436ea34-33cb-4abc-8d3b-4e0f7f83dd29
Commits
Reviewing files that changed from the base of the PR and between 62c2442 and 180ac98.
Files selected for processing: 5
.github/workflows/sdk-spec.yml
lib/src/flagsmith_client.dart
sdk-spec/steps.dart
test/fg/flagsmith_analytics_test.dart
test/fg/flagsmith_experiments_test.dart
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
nl -ba lib/src/flagsmith_config.dart | sed -n '1,90p'
Repository: Flagsmith/flagsmith-flutter-client
Length of output: 3937
Report scheduled failures when debug logging is disabled.
FlagsmithConfig.isDebug defaults to false, so log() produces no output for scheduled failures. syncAnalyticsData() rethrows after logging, but .ignore() now suppresses the unhandled asynchronous error that the previous timer callback exposed.
Report scheduled failures through a logger or callback that operates independently of isDebug.
Pending analytics remain in flagAnalytics after a failed send. However, close() cancels the timer without flushing them. This behaviour existed before this change and is not a regression caused by .ignore().
The reason will be displayed to describe this comment to others. Learn more.
Not changing this here, because it would break the SDK's logging convention. Every diagnostic in the SDK goes through FlagsmithClient.log(), which prints only when isDebug is set (lib/src/flagsmith_client.dart:30-35). That includes the event processor's failed flushes (lib/src/core/events/event_processor.dart:189,193), which are dropped the same way. syncAnalyticsData() already logs the failure through that path before rethrowing (lines 119-125), and .ignore() only stops the rethrow from becoming an uncaught async error. Before this change, the failure wasn't reported anywhere either: it crashed the app (this crash made every spec scenario after the first fail). Adding an error callback or a logger that ignores isDebug would be a new public API, and it should cover analytics and events alike, so it belongs in its own PR if maintainers want it. Agreed that close() not flushing pending analytics is pre-existing and out of scope here.
The reason will be displayed to describe this comment to others. Learn more.
Minor · Functional Correctness · Quick win
Supported by static analysis
Script executed:
sed -n 85,140p test/fg/flagsmith_analytics_test.dart
grep -n 'Timer\|analyticsInterval' lib/src/flagsmith_client.dart | head
Repository: Flagsmith/flagsmith-flutter-client
Length of output: 2265
Script executed:
set -o pipefail
printf'%s\n''--- client timer and analytics flow ---'
nl -ba lib/src/flagsmith_client.dart | sed -n '35,135p;690,735p'printf'%s\n''--- config interval declaration and docs ---'
rg -n -F --glob '*.dart' -e 'analyticsInterval' -e 'class FlagsmithConfig' lib testprintf'%s\n''--- client init and test setup ---'
nl -ba test/fg/flagsmith_analytics_test.dart | sed -n '1,145p'
Repository: Flagsmith/flagsmith-flutter-client
Length of output: 11993
Wait for the second scheduled analytics request.
analyticsInterval: 10 is 10 milliseconds, not 10 seconds. Failed sends are retried on the next Timer.periodic tick. Dart may skip delayed periodic callbacks, so the fixed 100 ms wait can observe fewer than two attempts.
Suggested fix
-import 'dart:convert';+import 'dart:async';+import 'dart:convert';
var attempts = 0;
+ final secondAttempt = Completer<void>();
scheduled.client.interceptors.add(InterceptorsWrapper(onRequest: (o, h) {
if (o.path == scheduled.config.analyticsURI) {
attempts++;
+ if (attempts == 2) {+ secondAttempt.complete();+ }
}
h.next(o);
}));
...
// When
await scheduled.getFeatureFlagValue('my_feature');
- await Future<void>.delayed(const Duration(milliseconds: 100));+ await secondAttempt.future.timeout(const Duration(seconds: 1));
The reason will be displayed to describe this comment to others. Learn more.
Applied in d76c743, with one change to the suggestion. Waiting for the second request (onRequest) let the test pass even with the fix reverted: tick 2 sends before tick 1's error is raised, so the test ended before the uncaught error surfaced. The test now waits for the second failed response (onError). By then the first failure has been fully handled. Reverting .ignore() fails the test 3 of 3 times with the uncaught DioException, and the suite passes 3 of 3 with the fix.
renovateBot
changed the title
chore(deps): update dependency flagsmith/sdk-spec to v0.6.0
chore(deps): update dependency flagsmith/sdk-spec to v0.7.0
Oct 29, 2026
The flag analytics timer left the error of a failed send unhandled, so a
network failure or an error response from Flagsmith crashed the app with
an uncaught exception. The timer now drops the error, which
syncAnalyticsData has already logged, and resends on the next tick.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 36a294b)
An exposure recorded by getExperimentFlag now carries the traits the
identity was evaluated with, as the other Flagsmith SDKs do, so that
experiment results can be analysed by trait.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit b5f536a)
Wires the spec's new steps to the SDK's event tracking: creating a
client with events enabled, getExperimentFlag, trackEvent and
trackExposureEvent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 180ac98)
…elay
A fixed 100 ms wait could see fewer scheduled sends than expected. The test
now waits for the second failed send, which also ensures the first failure
has been handled before the test ends.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit d76c743)
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
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.
This PR contains the following updates:
v0.5.0→v0.7.0Release Notes
Flagsmith/sdk-spec
v0.7.0Compare Source
What's Changed
New Contributors
Full Changelog: Flagsmith/sdk-spec@v0.6.0...v0.7.0
v0.6.0Compare Source
What's Changed
New Contributors
Full Changelog: Flagsmith/sdk-spec@v0.5.1...v0.6.0
v0.5.1Compare Source
What's Changed
Full Changelog: Flagsmith/sdk-spec@v0.5.0...v0.5.1
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.