Input and output schemas
The two JSON Schemas of a workflow, the rules both must follow, alternatives for the input, and where to find the full references.
Updated 13 November 2026 View as markdown
On this page
A workflow has two JSON Schema files. schemas/input.json describes what a user provides; Qsolve validates every run's input against it and builds the input form from it. schemas/output.json describes the answer answer() returns; Qsolve validates the answer against it and draws it from the schema's titles and units. Both use JSON Schema draft-07 with a few restrictions.
| Page | What it covers |
|---|---|
| This page | The shared rules, alternatives, and the check commands. |
| Input schema reference | Every input keyword and x-ui hint, and how the form is built. |
| Output schema reference | How the answer is validated and drawn, and every output hint. |
Rules both schemas must follow
qsolve lint and the platform reject a schema that breaks these rules:
| Rule | Lint code |
|---|---|
It is valid draft-07 ("$schema": "http://json-schema.org/draft-07/schema#") |
E020 |
It does not use pattern or patternProperties anywhere, because regular expressions can hang validation. Use enum, minLength or maxLength |
E021 |
Every $ref is local, starting with #, for example #/definitions/point |
E021 |
It does not use "format": "regex" |
E021 |
| It serialises to at most 256 KB | E022 |
Every example input in inputs.examples validates against the input schema |
E023 |
| It is a JSON object, and its path stays inside the repository | manifest load |
E022 is measured on the schema's JSON text, in characters, and applies to both files. E023 applies to the input schema only, and an input schema with no example is E024 (see The manifest).
Declare bounds so the form and the validator catch mistakes early: minItems, maxItems, minimum, maximum, maxLength. Match them to your manifest's envelope: max-cut allows 24 nodes in the manifest and says "maxItems": 24 in the schema.
Set additionalProperties: false at the top of the input schema so a misspelled field is an error rather than silently ignored. A failing input is refused with Invalid input at <path>: <message>, for example Invalid input at nodes: [] is too short. Checks a schema cannot express, such as "node names must be unique", belong in __init__, which raises WorkflowError with a message for the user.
The output schema is stricter in effect than it looks: an answer that does not match fails the run with Workflow produced an invalid answer: <message>. See the output schema reference.
Presentation hints with x-ui
x-ui is an extra object you may add to a property. It only affects how the form and the answer are drawn; the validator ignores it, so a wrong hint never rejects an input or an answer. The input form reads many hints (widget, labels_from, slider and more); the answer view reads only unit and format. Both are documented in full in the two reference pages above. Give every property a title: without one, the form and the answer show the property name with underscores turned into spaces.
Alternatives: one input, two descriptions
A top-level anyOf of required lists lets a user choose how to describe the problem. portfolio-optimization accepts either expected returns with a covariance matrix, or a history of returns:
"anyOf": [
{"title": "Expected returns and covariance", "required": ["expected_returns", "covariance"]},
{"title": "Historical returns", "required": ["returns_history"]}
]
The form shows these as alternatives, titled by each entry's title. Details, including the also hint, are in the input schema reference.
Check your schemas
qsolve validate . # loads both schemas and validates the example inputs
qsolve lint . # applies the restrictions above