microsoft / microsoft/kiota

Query parameter with allOf-wrapped single $ref to enum schema generates str instead of the enum type

Open
#8,108 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
3.8k
Forks
333
Avg merge
16h 29m
Merged PRs (30d)
116

Description

**Bug report**

When a query parameter's schema is written as `allOf: [{ $ref: "#/components/schemas/SomeEnum" }]` (a common pattern for attaching a `description` alongside a `$ref`, since plain JSON Schema doesn't allow sibling keys next to `$ref`), Kiota generates the parameter as `Optional[str]` instead of resolving it to the referenced enum type.

By contrast, a sibling parameter in the *same operation* whose schema uses a **direct** `$ref` (e.g. `items: {$ref: ...}` for an array parameter) resolves correctly to the generated enum type.

**Minimal repro spec:**
```json
{
"openapi": "3.0.1",
"info": { "title": "Repro API", "version": "1.0" },
"paths": {
"/widgets": {
"get": {
"operationId": "listWidgets",
"parameters": [
{
"name": "widgetType",
"in": "query",
"required": true,
"schema": { "allOf": [ { "$ref": "#/components/schemas/WidgetType" } ] }
},
{
"name": "statuses",
"in": "query",
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/WidgetStatus" }
}
}
],
"responses": {
"200": {
"description": "OK",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/WidgetListResponse" } } }
}
}
}
}
},
"components": {
"schemas": {
"WidgetType": { "type": "string", "enum": ["Basic", "Advanced"] },
"WidgetStatus": { "type": "string", "enum": ["Active", "Inactive", "Pending"] },
"WidgetListResponse": {
"type": "object",
"properties": { "items": { "type": "array", "items": { "type": "string" } } }
}
}
}
}
```

**Command:**
```
kiota generate --openapi repro-spec.json --language python --class-name ReproClient --namespace-name repro_client --exclude-backward-compatible --additional-data false --output repro-out
```

**Generated (`widgets_request_builder.py`):**
```python
statuses: list[WidgetStatus] = field(default_factory=list) # correct
widget_type: Optional[str] = None # expected: Optional[WidgetType]
```

**Expected:** `widget_type` should be typed as `Optional[WidgetType]`, consistent with how `statuses` resolves.

**Additional context:** Confirmed this is specific to Kiota's generator — `datamodel-code-generator` (Python, unrelated OpenAPI/JSON-Schema codegen pipeline) resolves the exact same `allOf`-wrapped `$ref` pattern correctly to the enum type. So the spec pattern isn't inherently ambiguous; this looks like a gap in how Kiota's `allOf`-with-single-`$ref` inlining interacts with parameter schema resolution (possibly related to, but not covered by, the "referenced schema in allOf was a primitive" fix in 1.22.0).

**Kiota version:** reproduced on 1.34.1 (latest) and 1.30.0
**Language:** Python (untested on other languages)

Contributor guide

Open the contributing guide

Research direction

Run the provided `kiota generate` command with `repro-spec.json` and inspect `widgets_request_builder.py`, comparing `widget_type` with `statuses`. Trace how the generator resolves the query parameter schema, then add coverage for a single-`$ref` `allOf` enum parameter so generation produces `Optional[WidgetType]`.

Written by the indexing model from the issue text.

Assessment

Tech stack
openapi, python
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.