Skip to content

[flagd] The two resolvers disagree on numeric coercion: in-process returns TYPE_MISMATCH, RPC returns 0 #420

Description

@aepfli

The two resolvers of this provider answer the same question differently, and I would like to know which one is intended before assuming either is wrong.

What I measured

float-flag resolves to 0.5. Requesting it through get_integer_details with a code default of 1:

resolver result
in-process 1 — the code default, with TYPE_MISMATCH
RPC 0no error code at all

Both against flagd-testbed:v3.8.0, same flag, same call, same run. The widening direction agrees:
integer-flag (10) requested as a float returns 10.0 from both.

So in-process rejects a lossy narrowing and RPC performs it silently.

Why I am asking rather than filing it as a bug

The rule this would be measured against is flagd's own, not OpenFeature's. OpenFeature has a
single numeric type — number is "a numeric value of unspecified type or size" — and no numbered
requirement says what a provider must do when a value does not fit the accessor it was asked
through; that is an open question of the provider contract
(open-feature/spec#430). flagd accepted a coercion
ADR for itself — coerce when lossless, TYPE_MISMATCH when information would be lost — tracked in
open-feature/flagd#1996.

Against that rule the in-process resolver is already correct and the RPC one is not. But that is
flagd's rule to interpret, which is why this is a question.

What does not depend on which answer is right: two transports of one provider disagreeing is a
vendor-neutrality problem on its own terms. An application that switches resolver= — a
configuration change, not a code change — gets a different value and a different error code for the
same flag and the same call. That is the property the conformance suite exists to check, occurring
inside a single provider.

Calibration from the other languages

Worth knowing before deciding, because it suggests where the fix belongs:

  • The Java and Go flagd providers narrow 0.5 to 0 with no error code in both resolvers
    — consistent with each other, both matching this repository's RPC behaviour.
  • This provider is the only one of the four whose two resolvers differ, and the only one where any
    resolver implements the ADR's lossy half.

So the in-process path here appears to be ahead of the other implementations rather than behind them.

Questions

  1. Is the in-process behaviour the intended one, with RPC yet to catch up?
  2. If so, is the gap in this provider's RPC path, or is it that the evaluation happens server-side
    there and the answer has to come from flagd itself?
  3. Is there a reason the two paths should be permitted to differ that I am missing?

Context

Found while building the cross-language provider conformance suite proposed in
open-feature/spec#417. Both resolvers now declare
the @numeric-coercion capability and the results record the difference, with a known-deviation
entry against the RPC suite only — the in-process suite does not carry one, because it does not have
the defect. Nothing is blocked either way.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs TriageThis issue needs to be investigated by a maintainerquestionFurther information is requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions