Skip to content

Comments

[Bugfix] Fix AttributeError when passing StructuredOutputsParams to CompletionRequest#35234

Closed
pks wants to merge 1 commit intovllm-project:mainfrom
pks:fix/structured-outputs-params-get-attr
Closed

[Bugfix] Fix AttributeError when passing StructuredOutputsParams to CompletionRequest#35234
pks wants to merge 1 commit intovllm-project:mainfrom
pks:fix/structured-outputs-params-get-attr

Conversation

@pks
Copy link

@pks pks commented Feb 24, 2026

Summary

The check_structured_outputs_count model validator on CompletionRequest and ChatCompletionRequest uses mode="before" and calls .get() on the structured_outputs value, assuming it is always a dict. However, the field is typed as StructuredOutputsParams | None, so passing a dataclass instance is a valid usage but crashes with:

  AttributeError: 'StructuredOutputsParams' object has no attribute 'get'

This PR handles both dict and StructuredOutputsParams inputs by checking the type and using getattr for dataclass instances.

Reproduction

from vllm.entrypoints.openai.completion.protocol import CompletionRequest
from vllm.sampling_params import StructuredOutputsParams

# Crashes on v0.12.0 through v0.15.1
CompletionRequest(
    model="my-model",
    prompt="hello",
    max_tokens=100,
    structured_outputs=StructuredOutputsParams(regex=r"^ [\s\S]*"),  # could be fixed w/ structured_outputs={"regex": " [\s\S]*"}
)
# AttributeError: 'StructuredOutputsParams' object has no attribute 'get'

Test plan

  • Verified CompletionRequest accepts StructuredOutputsParams object (was crashing)
  • Verified CompletionRequest still accepts dict (existing behavior)
  • Verified CompletionRequest still accepts None
  • Verified multi-constraint validation still rejects for both dict and object inputs
  • Verified ChatCompletionRequest same as above

Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.
  • (Optional) Release notes update. If your change is user facing, please update the release notes draft in the Google Doc.

…ompletionRequest

The `check_structured_outputs_count` model validator uses `mode="before"`,
so it receives raw input data. It calls `.get()` on the `structured_outputs`
value, which only works for dicts. However the field is typed as
`StructuredOutputsParams | None`, so passing a dataclass instance is valid
but crashes with:

    AttributeError: 'StructuredOutputsParams' object has no attribute 'get'

Handle both dict and StructuredOutputsParams inputs by checking the type
and using `getattr` for dataclass instances.

Fixes both `CompletionRequest` and `ChatCompletionRequest`.

Signed-off-by: Patrick Simianer <patrick@lilt.com>
@mergify mergify bot added frontend bug Something isn't working labels Feb 24, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an AttributeError in check_structured_outputs_count for CompletionRequest and ChatCompletionRequest. The error occurred when structured_outputs was a StructuredOutputsParams object instead of a dictionary. The submitted change corrects this by checking the type of structured_outputs and using either getattr for objects or .get() for dictionaries to access its properties. The fix is applied consistently in both chat_completion/protocol.py and completion/protocol.py. The changes correctly resolve the described bug.

@mergify
Copy link

mergify bot commented Feb 24, 2026

Hi @pks, the pre-commit checks have failed. Please run:

uv pip install pre-commit
pre-commit install
pre-commit run --all-files

Then, commit the changes and push to your branch.

For future commits, pre-commit will run automatically on changed files before each commit.

Tip

Is mypy or markdownlint failing?
mypy and markdownlint are run differently in CI. If the failure is related to either of these checks, please use the following commands to run them locally:
# For mypy (substitute "3.10" with the failing version if needed)
pre-commit run --hook-stage manual mypy-3.10
# For markdownlint
pre-commit run --hook-stage manual markdownlint

@pks pks closed this Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant