Fix Decimal JSON serialization in semantic layer query results #475
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
DISCLAIMER: this PR was created with the assistance of Claude Code, but I reviewed the small change set. If the project policy is to not accept these please let me know and I will close the PR.
Summary
Fix JSON serialization error when querying metrics that return Decimal values from the dbt Semantic Layer.
What Changed
from decimal import Decimalimport insrc/dbt_mcp/semantic_layer/client.pyDateTimeEncodertoExtendedJSONEncoderand extended it to handleDecimalobjects by converting them tofloatjson.dumps()call to use the renamed encoder classWhy
When querying metrics from the dbt Semantic Layer, PyArrow tables with
decimal128/decimal256columns return PythonDecimalobjects viatable.to_pylist(). The existingDateTimeEncoderonly handleddatetimeanddateobjects, causingjson.dumps()to fail with:MCP response showing the error:
{ "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "Object of type Decimal is not JSON serializable" } ], "isError": false } }Related Issues
Closes #
Related to #
Checklist
Additional Notes
Manually verified with a
query_metricscall that previously failed:{ "limit": 3, "metrics": ["sqls"], "group_by": [{"name": "metric_time", "grain": "MONTH", "type": "time_dimension"}], "order_by": [{"name": "metric_time", "descending": true}] }Now returns successfully:
[ {"metric_time__month": "2025-12-01T00:00:00+00:00", "sqls": 245.0}, {"metric_time__month": "2025-11-01T00:00:00+00:00", "sqls": 134.0}, {"metric_time__month": "2025-10-01T00:00:00+00:00", "sqls": 9373.0} ]