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.
Summary
ConfigClient.set()andConfigClient.set_many()(and their async equivalents) raiseInvalidArgumentErrorfor every field whose declared schema type is notstring.Root cause
make_string_typed_value()insdk/src/opendecree/_stubs.pyunconditionally constructs: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'scheckType()(present since the repo's first commit) requires the populated oneof variant to match the field'sFieldTypeexactly:So
client.set(tenant_id, "app.debug", "true")sendsTypedValue(string_value="true"), and the server rejects it withfield app.debug: expected bool value.Impact
set()andset_many()are unusable for any field of typebool,integer,number,time,duration,url, orjson— i.e. every type exceptstring. Both call sites (client.pylines ~297 and ~387) go throughmake_string_typed_value().Reproduction
Suggested fix
make_string_typed_value()(or its caller) needs to look up the field's declaredFieldTypefrom the schema and construct the matchingTypedValueoneof variant (bool_value,integer_value,number_value,duration_value, etc.), parsing the stringvalueaccordingly. 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_limitcrashed 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 ofset()/set_many()for typed fields.