Skip to content

client.set()/set_many() always send string_value, fail for non-string field types #139

@zeevdr

Description

@zeevdr

Summary

ConfigClient.set() and ConfigClient.set_many() (and their async equivalents) raise InvalidArgumentError for every field whose declared schema type is not string.

Root cause

make_string_typed_value() in sdk/src/opendecree/_stubs.py unconditionally constructs:

TypedValue(string_value=value)

regardless of the target field's declared type. Its docstring claims "the server accepts string values for all field types and performs type coercion based on the schema definition" — but the server has never done this. internal/validation/validator.go's checkType() (present since the repo's first commit) requires the populated oneof variant to match the field's FieldType exactly:

case pb.FieldType_FIELD_TYPE_BOOL:
    if _, ok := tv.Kind.(*pb.TypedValue_BoolValue); !ok {
        return fmt.Errorf("expected bool value")
    }

So client.set(tenant_id, "app.debug", "true") sends TypedValue(string_value="true"), and the server rejects it with field app.debug: expected bool value.

Impact

set() and set_many() are unusable for any field of type bool, integer, number, time, duration, url, or json — i.e. every type except string. Both call sites (client.py lines ~297 and ~387) go through make_string_typed_value().

Reproduction

with ConfigClient("localhost:9090", subject="x") as client:
    client.set(tenant_id, "app.debug", "true")
# opendecree.errors.InvalidArgumentError: field app.debug: expected bool value

Suggested fix

make_string_typed_value() (or its caller) needs to look up the field's declared FieldType from the schema and construct the matching TypedValue oneof variant (bool_value, integer_value, number_value, duration_value, etc.), parsing the string value accordingly. This likely requires either a schema lookup before the write or a server-side coercion path — needs design discussion.

Found via

While fixing #133 (examples/setup.py + set_many examples), the example for app.debug/server.rate_limit crashed in CI with this error. Worked around by scoping the examples to string-typed fields (app.name, payments.currency) — but the underlying defect remains and blocks any real use of set()/set_many() for typed fields.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: P0Blocks alpha or releasesize: LLarger effort — multiple days, design decisions needed

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions