Serina G
03/25/2026, 6:46 PMProcess for flow run 'abc-123' exited with status code: 1 when ideally it would fail with the actual validation error, or even better, the form would not be submitted. Is this a known issue?Marvin
03/25/2026, 6:46 PMMarvin
03/25/2026, 6:51 PM@flow has validate_parameters=True by default). If validation fails, the run should enter a Failed state with a message containing the Pydantic error. In some views you may still see a generic “Process exited with status code: 1” log line, but the detailed reason should be in the flow run’s state message.
How to get the form to block submission
- Expose your constraints in the JSON schema so the UI can validate them pre-submit. In practice, that means using Field constraints or Annotated types so Prefect can derive them into the parameter schema:
from typing import Annotated
from pydantic import BaseModel, Field
from prefect import flow
class Params(BaseModel):
# UI can enforce these because they become JSON Schema constraints
name: Annotated[str, Field(min_length=3)]
age: Annotated[int, Field(ge=0, le=120)]
@flow
def my_flow(params: Params):
...
- If you’re using only custom validators like @field_validator, those will run at execution time, not in the UI.
Where to find the actual validation error
- Open the flow run page and check the latest state (Failed). Expand it to see the full state message. That message should include the Pydantic ValidationError details (e.g., which field failed and why).
- You can also fetch it via the API/Client and inspect flow_run.state.message.
If you only see “exited with status code: 1”
- That’s usually a generic subprocess summary message. There should still be a Failed (or Crashed) state with a message that includes the validation error. If you don’t see it, that may be an issue worth investigating.
- To help us reproduce, could you share:
- Prefect version (assuming 3.x?), Pydantic version
- How you’re launching (Cloud/Server, which worker type)
- A minimal example of your parameter model (showing the validators)
- A screenshot or copy of the run’s latest state message
Notes
- Prefect 3.x uses Pydantic v2 under the hood. Custom validators should be declared with @field_validator / @model_validator (not the v1 @validator).
- The UI can only enforce what’s present in the generated parameter schema. Using Field(...) constraints or Annotated[...] is the best way to make the form block invalid submissions.Serina G
03/25/2026, 6:57 PM@model_validator , Prefect 3.x, Pydantic v2, ECS task, Prefect Cloud, the state message is the one I sent overMarvin
03/25/2026, 6:57 PMMarvin
03/25/2026, 6:59 PM@model_validator at form time.
- To make the UI block submission, encode those rules as JSON Schema constraints (e.g., via Field(...) constraints or Annotated[...]) so the schema reflects them. Example:
from typing import Annotated
from pydantic import BaseModel, Field
from prefect import flow
class Params(BaseModel):
x: Annotated[int, Field(ge=0)] # UI can enforce this pre-submit
@flow
def my_flow(p: Params):
...
- If your deployment doesn’t have a parameter schema attached, the checkbox won’t have any effect. In Cloud, open the deployment and confirm a parameter schema is present. If it’s missing, redeploy the flow so the schema is generated from the function signature.
2) Why the run only shows “exited with status code: 1”
- Pydantic v2 validators (including @model_validator) do run at execution time in Prefect 3.x. If validation fails, Prefect should put the run into a Failed state with a message like “Validation of flow parameters failed with error: …” including the Pydantic details.
- If you only see “Process for flow run ... exited with status code: 1”, that typically indicates the process crashed before Prefect could attach the detailed failure message — you’ll often see a Crashed state instead of Failed in those cases.
- This isn’t a known widespread issue specific to @model_validator, but it can happen in remote infrastructure (ECS) if the process terminates early (e.g., before Prefect’s engine handles the exception). We’d like to confirm whether your run state is Failed or Crashed.
Quick checks to narrow this down
- In the run’s page, check the latest state type:
- If it’s Failed, expand the state to see the full state message — that’s where the Pydantic error should appear.
- If it’s Crashed, Prefect likely didn’t get a chance to write the validation error. Check the ECS task logs (CloudWatch) for the detailed traceback.
- Enable more logging to surface the validation message:
- Add env var PREFECT_LOGGING_LEVEL=DEBUG to the ECS task definition.
- Try a minimal reproducer:
from pydantic import BaseModel, model_validator
from prefect import flow
class P(BaseModel):
x: int
@model_validator(mode="after")
def check_x(self):
if self.x < 0:
raise ValueError("x must be >= 0")
return self
@flow
def f(p: P):
return p.x
Deploy and run with p={"x": -1}. Expected: Failed state with a message including the Pydantic error.
If the minimal example still only shows the generic “status code: 1” in Cloud for ECS runs, that points to an execution-time crash before Prefect writes the Failed state (possibly an infra/logging nuance). In that case, please share:
- Exact Prefect version (3.x.y) and the worker/flow image tag in your ECS task
- Whether the run state is Failed or Crashed
- The snippet of your @model_validator and flow signature
- A snippet from the ECS task logs, if available
Workarounds/next steps
- To prevent invalid submissions from the UI, expose constraints in the schema with `Field(...)`/`Annotated[...]` as shown above.
- To make the error visible to users, you can also add a Cloud Automation for “Flow run enters Failed” and include {{ flow_run.state_message }} in the notification while we confirm what’s happening on ECS.
If you can provide the above details or a small repro, I’m happy to try to reproduce and file an issue if it turns out the engine isn’t surfacing the Pydantic error on ECS as expected.Serina G
03/25/2026, 7:01 PMMarvin
03/25/2026, 7:01 PMMarvin
03/25/2026, 7:02 PM@flow() then def my_flow(p: MyModel): ... with @model_validator on MyModel (and don’t set validate_parameters=False).
- Less ideal (and can lead to generic messages): accepting dict (or untyped) and then constructing MyModel later inside the flow or in a task.
- Make sure the model isn’t being constructed at import time. Any exception raised before the engine enters the run context (e.g., module-level code) can result in a generic “status code: 1” message.
- On the flow run page, open:
- States panel: expand the latest Failed state and copy the full “State message”.
- Logs tab: copy the first error/traceback line you see around the time the run starts.
- ECS task logs (CloudWatch): check for a traceback right after the task starts.
If you can share a minimal repro, I can try to replicate exactly what you’re seeing. For example, this should produce a Failed state with a clear validation message:
from pydantic import BaseModel, model_validator
from prefect import flow
class P(BaseModel):
x: int
@model_validator(mode="after")
def check(self):
if self.x < 0:
raise ValueError("x must be >= 0")
return self
@flow # validate_parameters defaults to True in Prefect 3.x
def f(p: P):
return p.x
Deploy and run with p={"x": -1}. Expected: a Failed state with a message indicating the validation error. If this minimal case still shows only “status code: 1” in the state message on ECS, that points to the error being swallowed before the engine records details — and I’ll open an issue for us to fix.
In parallel, if you want the UI form to block submission, encode the rules as JSON Schema constraints so the “Validate parameters” checkbox can enforce them pre-submit (e.g., Field(min_length=..., ge=..., le=...) or Annotated[...]), since the UI cannot run @model_validator at form time.
If you can share:
- Your flow signature (just the def line) and the Pydantic model with the @model_validator
- Whether validate_parameters is left as default
- A snippet of the run’s full Failed state message and the first relevant log line
…I’ll help chase this down and, if needed, file a bug so those validation details reliably show up in the Failed state.Serina G
03/25/2026, 7:07 PM18:37:46.747 | *ERROR* | prefect.flow_runs.runner - Process for flow run 'augmented-mussel' exited with status code: 1Marvin
03/25/2026, 7:07 PMMarvin
03/25/2026, 7:08 PM