Skip to content

feat!: reject unsupported remoteEval configurations and add setUrl - #189

Open
vazarkevych wants to merge 1 commit into
fix/remote-eval-flowfrom
feature/remote-eval-config
Open

vazarkevych wants to merge 1 commit into
fix/remote-eval-flowfrom
feature/remote-eval-config

Conversation

@vazarkevych

@vazarkevych vazarkevych commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Validates the remote-evaluation configuration at startup and adds setUrl. Supersedes #173 and section 3 of #176, which disagreed on the rules; this follows the JS SDK.

Depends on #187 — this branch is built on it; only the last commit belongs to this PR.

Validation rules

initialize() throws an ArgumentError for the remote-eval configurations the GrowthBook constructor in the JS SDK rejects, and only those:

Configuration with remoteEval: true Result JS SDK
empty apiKey rejected Missing clientKey
encryptionKey set rejected Encryption is not available for remoteEval
host on GrowthBook Cloud, i.e. hostname ending in growthbook.io (subdomains included) rejected Cannot use remoteEval on GrowthBook Cloud
stickyBucketService set allowed not rejected
backgroundSync: true allowed not rejected

How this resolves the open questions from #173:

  • Streaming is allowed. Since fix: re-evaluate remotely on every context change and discard stale responses #187, a stream event in remote-eval mode triggers a fresh POST instead of applying the unevaluated payload, and the proxy's features-updated event is handled. This was verified against a GrowthBook Proxy.
  • Sticky bucketing is allowed, as in the JS SDK.
  • GrowthBook subdomains are rejected, as in the JS SDK (hostname.match(/growthbook\.io$/i)). A URL that only contains the string elsewhere, e.g. growthbook.io.example.com or a path segment, is accepted.

setUrl

setUrl(String url) sets the URL used for URL targeting, like setURL in the JS SDK. If the URL is unchanged it does nothing; in remote-eval mode the returned Future completes after the fresh evaluation.

The remote-eval payload now carries url ("" when unset, as in the JS SDK). Neither #173 nor #176 sent it, so a setUrl refetch would not have reached URL-targeting rules on the server.

Breaking change

An app that starts with one of the rejected configurations, and silently got no working remote evaluation, now fails at startup. Release target: 5.0.0.

Test plan

  • New remote_eval_test.dart (13 tests):
    • each rejection, all cloud hosts including a tenant subdomain and mixed case, hosts that only contain the string;
    • allowed sticky bucketing, streaming and plain configuration;
    • no validation without remoteEval;
    • url in the payload (unset and configured);
    • setUrl with and without remote evaluation, and an unchanged URL.
  • The tests fail when validation is disabled, url is dropped from the payload, or the unchanged-URL check is removed.
  • gb_sdk_remote_eval_test.dart now uses a self-hosted test host, since example.growthbook.io is rejected.
  • Against Flutter 3.27.0 (the CI version): dart analyze --fatal-infos, dart format and flutter test (3 runs) clean.

BREAKING CHANGE: initialize() throws ArgumentError for a remoteEval configuration with an empty apiKey, an encryptionKey, or a GrowthBook Cloud host.
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.

1 participant