open-feature / open-feature/go-sdk
[BUG] evaluate() returns errors without an ErrorCode or Reason on the UTF-8 and before-hook paths
- Dominant language
- Go
- Stars
- 250
- Forks
- 62
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 25
Description
## Observed behavior
Two of `Client.evaluate`'s early returns hand back an error with `ErrorCode` and `Reason` both empty.
**Invalid UTF-8 flag key** — returns a parse error, but nothing is written to `evalDetails`, and the error hooks don't run either:
https://github.com/open-feature/go-sdk/blob/a0892c296bd8b6d55188687e49dcc7692594f015/openfeature/client.go#L665-L666
**Before-hook error** — the error hooks do run, but the fields are still unset:
https://github.com/open-feature/go-sdk/blob/a0892c296bd8b6d55188687e49dcc7692594f015/openfeature/client.go#L712-L715
Contrast the NOT_READY and FATAL short-circuits just above, which set `Reason`, `ErrorCode` and `ErrorMessage` before returning.
## Expected Behavior
Per [1.4.7](https://openfeature.dev/specification/sections/flag-evaluation#requirement-147), in cases of abnormal execution the evaluation details' error code field **MUST** contain an error code; [1.4.8](https://openfeature.dev/specification/sections/flag-evaluation#requirement-148) adds that the reason **SHOULD** indicate an error.
A before-hook error is unambiguously abnormal execution under [4.4.7](https://openfeature.dev/specification/sections/hooks#requirement-447), so 1.4.7 applies squarely there. The UTF-8 case is a parse failure before evaluation begins, and `ParseErrorCode` is the natural code.
The error hooks not running on the UTF-8 path looks like a separate defect on the same return — worth confirming whether that's deliberate.
## Scope
**Not** the after-hook path, which has the same symptom (`Reason` stays `STATIC`, `ErrorCode` empty) but isn't decidable yet: whether an after-hook error counts as abnormal execution at all is under discussion in #566. That path should be revisited once that settles.
## Related
- #542 — the `FlagMetadata` gap on these same returns. Same lines, separate fix; keeping them in different PRs.
- #537 / #538 — the same class of defect on the typed accessors' TYPE_MISMATCH paths.
Contributor guide
Research direction
Start in client.go at the Client.evaluate early returns linked in the issue, then compare them with the nearby NOT_READY and FATAL short-circuits. Check the existing evaluation tests and specification references for the invalid UTF-8 and before-hook cases. Done means both paths return populated error details, with the UTF-8 hook behavior confirmed as intentional or covered separately.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100