Skip to content

Use the const value when a literal branch is selected in a schema form - #22911

Draft
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin1/oss-8166-literal-value-is-invalid-when-default-is-another-type
Draft

Use the const value when a literal branch is selected in a schema form#22911
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin1/oss-8166-literal-value-is-invalid-when-default-is-another-type

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

closes #22909

This PR makes the React schema form use the const value of a union branch.

Pydantic gives a Literal in a union an anyOf definition with a const and no default:

{
  "anyOf": [
    { "items": { "type": "string" }, "type": "array" },
    { "const": "bar", "type": "string" },
    { "type": "null" }
  ]
}

The user cannot type the value of a const, and the form did not supply it. When the user selected the literal branch, the value stayed empty. The form did not show an error, and it sent null for the parameter. Thus the user could not give the literal value, and the run got the wrong value.

Details

The form now does two things:

  • When the user selects a branch that has no value, the form emits the const of that branch.
  • Branch selection prefers a definition whose const is equal to the value, before a definition that only has the same type as the value. A union with Literal["bar"] and str in it now shows the literal branch for the value "bar", and the str branch for other strings.

Tests:

  • ui-v2/src/components/schemas/schema-form-input-any-of.test.tsx — the form emits "bar" when the user selects the literal branch of list[str] | Literal["bar"] | None.
  • ui-v2/src/components/schemas/utilities/getIndexForAnyOfPropertyValue.test.ts — index resolution prefers the const match, and keeps the type match when no const is equal to the value.

The behavior is also verified in a browser against a local server. See the comment below.

The same defect is in the Vue schema form. The change for the V1 UI is in PrefectHQ/prefect-ui-library#3133, and the change for the Cloud UI is in PrefectHQ/nebula-ui#7070.

Checklist

  • This pull request references any related issue by including "closes <link to issue>"
  • If this is a complex change, a maintainer has confirmed the proposed approach on the linked issue.
  • If this pull request adds or changes functionality, it includes tests or explains why tests are not needed.
  • If this pull request changes user-facing behavior, it updates documentation or explains why documentation is not needed.
    • The change corrects form behavior only, so no documentation change is necessary.
  • If this pull request removes docs files, it includes redirect settings in mint.json.
  • If this pull request adds functions or classes, it includes helpful docstrings.

Link to Devin session: https://app.devin.ai/sessions/c7d997cb25b0431786119152836c2251

…a form

A pydantic Literal in a union becomes an anyOf definition with a const and no default. The React schema form left that branch empty, so a required parameter stayed invalid when the deployment default was another type in the union.

The form now emits the const as the value for that branch, and branch selection prefers a definition whose const matches the value over a definition that only matches its type.

OSS-8166

Co-authored-by: Alexander Streed <alex.s@prefect.io>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions github-actions Bot added bug Something isn't working ui Related to the Prefect web interface labels Aug 21, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Runtime verification of the deployment Run form (ui-v2)

Tested against a local Prefect server with the reporter's deployment (foo: list[str] | None | Literal["bar"], deployed with parameters={"foo": None}), comparing this branch (:5173) against its base commit in a separate worktree (:5174).

After (this branch): the str branch fills with bar, and the run gets {"foo": "bar"}

fixed str tab populated with bar
fixed flow run parameters foo bar

Before (base commit): the literal branch stays empty, and the form sends null

pre-fix str tab empty
pre-fix flow run parameters foo null

The form does not show a validation error on the base commit. Submit is accepted, and the run gets {"foo": null}. The user cannot give the literal value, and the wrong value goes to the run.

Regression: the array branch and the null branch continue to work
  • list branch, then "Add item", then hello gives run parameters {"foo": ["hello"]} list params
  • str branch, then back to None, gives run parameters {"foo": null} null params

Parameters of the created runs, from GET /api/flow_runs/filter:

{'foo': 'bar'}       # this branch, str branch
{'foo': ['hello']}   # this branch, list branch
{'foo': None}        # this branch, None branch
{'foo': None}        # base commit, str branch selected (the defect)

Not covered: the V1 Vue form (PrefectHQ/prefect-ui-library#3133) was not exercised in a browser.

Verified by Devin — https://app.devin.ai/sessions/c7d997cb25b0431786119152836c2251

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ui Related to the Prefect web interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Literal value is invalid when default is another type

0 participants