What happened?
The OpenAPI document served by /openapi.json describes the successful response for:
GET /api/v2/tenants/{tenant}/databases
as:
{
"$ref": "#/components/schemas/Vec"
}
However, that Vec component contains the collection shape (configuration_json, database, log_position, version, etc.). The endpoint actually returns database objects such as:
[
{
"id": "00000000-0000-0000-0000-000000000000",
"name": "default_database",
"tenant": "default_tenant"
}
]
This breaks generated clients that correctly follow the published schema. For example, a generated .NET client deserializes the response as a collection model and fails because configuration_json, database, log_position, and version are absent.
The expected 200 response schema is:
{
"type": "array",
"items": {
"$ref": "#/components/schemas/Database"
}
}
Likely source of the collision:
- The route annotation uses
body = ListDatabasesResponse:
|
path = "/api/v2/tenants/{tenant}/databases", |
|
summary = "List databases", |
|
description = "Lists all databases for a tenant.", |
|
tag = "Database", |
|
security( |
|
("ApiKeyAuth" = []) |
|
), |
|
responses( |
|
(status = 200, description = "List of databases", body = ListDatabasesResponse), |
|
(status = 401, description = "Unauthorized", body = ErrorResponse), |
|
(status = 500, description = "Server error", body = ErrorResponse) |
|
), |
|
params( |
|
("tenant" = String, Path, description = "Tenant UUID", example = "1e30d217-3d78-4f8c-b244-79381dc6a254"), |
|
("limit" = Option<u32>, Query, description = "Limit for pagination", minimum = 1, example = 10), |
|
("offset" = Option<u32>, Query, description = "Offset for pagination", minimum = 0, example = 0) |
|
), |
|
extensions( |
|
("x-codeSamples" = json!([ |
|
{ |
|
"lang": "terminal", |
|
"label": "List Databases", |
|
"source": "chroma db list" |
|
} |
|
])) |
|
) |
|
)] |
|
async fn list_databases( |
|
headers: HeaderMap, |
|
Path(tenant): Path<String>, |
|
Query(ListDatabasesParams { limit, offset }): Query<ListDatabasesParams>, |
|
State(mut server): State<FrontendServer>, |
|
) -> Result<Json<ListDatabasesResponse>, ServerError> { |
ListDatabasesResponse is Vec<Database>:
|
pub type ListDatabasesResponse = Vec<Database>; |
ListCollectionsResponse is separately Vec<Collection>:
|
pub type ListCollectionsResponse = Vec<Collection>; |
It appears these aliases are both represented as a shared OpenAPI component named Vec, with the collection item schema winning. An explicit array response schema (for example, an inline [Database] response in the utoipa annotation) or uniquely named response wrapper should avoid the collision.
Downstream reproduction and workaround: tryAGI/Chroma#144
The downstream generation pipeline temporarily rewrites only this response to array<Database>; after regeneration, the exact call against chromadb/chroma:latest returns default_database, and the full integration suite plus trimming checks pass.
Versions
- OpenAPI
info.version: 1.0.0
- OpenAPI version:
3.1.0
- Source snapshot inspected:
93652ec0869489b803fe1682427fc02bd47bec14
- Runtime reproduction: current
chromadb/chroma:latest container on 2026-08-26
- Client consumer:
tryAGI.Chroma (System.Text.Json)
Relevant log output
System.Text.Json.JsonException: JSON deserialization for type Chroma.VecItem was missing required properties including: configuration_json; database; log_position; version.
What happened?
The OpenAPI document served by
/openapi.jsondescribes the successful response for:GET /api/v2/tenants/{tenant}/databasesas:
{ "$ref": "#/components/schemas/Vec" }However, that
Veccomponent contains the collection shape (configuration_json,database,log_position,version, etc.). The endpoint actually returns database objects such as:[ { "id": "00000000-0000-0000-0000-000000000000", "name": "default_database", "tenant": "default_tenant" } ]This breaks generated clients that correctly follow the published schema. For example, a generated .NET client deserializes the response as a collection model and fails because
configuration_json,database,log_position, andversionare absent.The expected 200 response schema is:
{ "type": "array", "items": { "$ref": "#/components/schemas/Database" } }Likely source of the collision:
body = ListDatabasesResponse:chroma/rust/frontend/src/server.rs
Lines 837 to 869 in 93652ec
ListDatabasesResponseisVec<Database>:chroma/rust/types/src/api_types.rs
Line 492 in 93652ec
ListCollectionsResponseis separatelyVec<Collection>:chroma/rust/types/src/api_types.rs
Line 646 in 93652ec
It appears these aliases are both represented as a shared OpenAPI component named
Vec, with the collection item schema winning. An explicit array response schema (for example, an inline[Database]response in the utoipa annotation) or uniquely named response wrapper should avoid the collision.Downstream reproduction and workaround: tryAGI/Chroma#144
The downstream generation pipeline temporarily rewrites only this response to
array<Database>; after regeneration, the exact call againstchromadb/chroma:latestreturnsdefault_database, and the full integration suite plus trimming checks pass.Versions
info.version:1.0.03.1.093652ec0869489b803fe1682427fc02bd47bec14chromadb/chroma:latestcontainer on 2026-08-26tryAGI.Chroma(System.Text.Json)Relevant log output