Theom
11/06/2025, 2:33 PMMarvin
11/06/2025, 2:33 PMMarvin
11/06/2025, 2:38 PMPREFECT_RESULTS_LOCAL_STORAGE_PATH is a global default. If you want different locations per workflow, set result_storage on each flow. This overrides the global default.
Option A (recommended) — set result_storage per flow:
from prefect import flow, serve
from prefect.filesystems import LocalFileSystem
@flow(name="flow_a", result_storage=LocalFileSystem(basepath="/var/prefect-results/flow_a"))
def flow_a():
...
@flow(name="flow_b", result_storage=LocalFileSystem(basepath="/var/prefect-results/flow_b"))
def flow_b():
...
if __name__ == "__main__":
serve(
flow_a.to_deployment(name="flow-a"),
flow_b.to_deployment(name="flow-b"),
)
Tip: You can also pass a plain path string for local storage:
@flow(result_storage="/var/prefect-results/flow_a")
def flow_a():
...
Option B — set the env var per deployment via job variables:
d1 = flow_a.to_deployment(
name="flow-a",
job_variables={"env": {"PREFECT_RESULTS_LOCAL_STORAGE_PATH": "/var/prefect-results/flow_a"}}
)
d2 = flow_b.to_deployment(
name="flow-b",
job_variables={"env": {"PREFECT_RESULTS_LOCAL_STORAGE_PATH": "/var/prefect-results/flow_b"}}
)
serve(d1, d2)
If both are set, the explicit result_storage on the flow takes precedence over the env default.
References:
- Results and result storage (Prefect 3)
- Settings reference
- Customize job variables (per-deployment env)
- LocalFileSystem source
- Result storage resolutionTheom
11/12/2025, 9:15 AMTypeError: Result storage configuration must be persisted server-side. Please call `.save()` on your block before passing it in.
When using a plain string, I have the following error:
ValueError: Unable to find block document named my_path for block typeMarvin
11/12/2025, 9:15 AMMarvin
11/12/2025, 9:20 AMLocalFileSystem(basepath=my_path) directly, Prefect requires that block to be saved server-side so it can be referenced in future runs/deployments. That’s why you see: “Result storage configuration must be persisted server-side. Please call `.save()`…”
- When you pass a plain string like "my_path", Prefect interprets strings as references to saved blocks (not file paths). Since there’s no saved block with that name, you see: “Unable to find block document named my_path…”.
How to fix it (choose one of these):
1) Save a LocalFileSystem block, then reference it
- Save once (e.g., in a setup script or a notebook):
from prefect.filesystems import LocalFileSystem
fs = LocalFileSystem(basepath="/absolute/path/for/results")
fs.save("my-results", overwrite=True) # creates a saved block named "my-results"
- Option A: Reference the saved block by slug in your flow (recommended and most portable):
from prefect import flow
@flow(result_storage="local-file-system/my-results")
def my_flow():
...
- Option B: Load the saved block and pass the block object:
from prefect import flow
from prefect.filesystems import LocalFileSystem
@flow(result_storage=LocalFileSystem.load("my-results"))
def my_flow():
...
2) Pass a Path object (not a string)
If you just want a local path without creating a saved block, pass a pathlib.Path object. Prefect will automatically wrap it in a LocalFileSystem under the hood:
from pathlib import Path
from prefect import flow
@flow(result_storage=Path("/absolute/path/for/results"))
def my_flow():
...
Note: A plain string like "/tmp/results" will be treated as a block reference and fail; use Path("/tmp/results") instead.
Where to set this:
- Set result_storage on the @flow and/or @task decorators. This configuration is included in deployments. There is no result_storage parameter on flow.deploy(...) in 3.x.
A few extra notes:
- If you set result_storage, Prefect will enable persist_result=True automatically unless you override it.
- Double-check the class name: it’s LocalFileSystem (not LocaFileSystem).
- Docs for reference:
- Results (Prefect 3.x)
- Blocks overview
- LocalFileSystem API
If you can share how you’re applying result_storage today (decorator vs. elsewhere) and your exact my_path value, I can tailor the snippet to your setup.Theom
11/12/2025, 9:25 AMTypeError: Result storage configuration must be persisted server-side. Please call.save()` on your block before passing it in.` error. Thanks, I'll ask the community.Marvin
11/12/2025, 9:25 AMMarvin
11/12/2025, 9:28 AMresult_storage should work in Prefect 3.x, but there’s a known issue in some 3.x releases (e.g., 3.0.10) where passing a pathlib.Path still triggers the “persisted server-side” error. Reference: Issue #15794.
Workarounds that will unblock you today:
- Save a LocalFileSystem block and reference it by slug (most reliable)
from prefect.filesystems import LocalFileSystem
fs = LocalFileSystem(basepath="/absolute/path/for/results")
fs.save("my-results", overwrite=True) # saves a block named "my-results"
Then in your flow:
from prefect import flow
@flow(result_storage="local-file-system/my-results")
def my_flow():
...
Or:
from prefect import flow
from prefect.filesystems import LocalFileSystem
@flow(result_storage=LocalFileSystem.load("my-results"))
def my_flow():
...
- If you prefer Path and are hitting the bug, try upgrading to the latest 3.x; if the issue persists in your version, stick with the saved-block approach above.
Notes:
- Strings like "my_path" are interpreted as block slugs, not filesystem paths — hence the “Unable to find block document named my_path” error.
- result_storage belongs on the `@flow`/`@task` decorator; it’s not a parameter to flow.deploy(...).
- If your deployment runs remotely, make sure the path you set is accessible in that runtime.
If you share your Prefect version and how you’re setting result_storage (decorator vs with_options), I can confirm whether you’re on an affected release and suggest the smallest change. If you’d rather take it to the community, totally fine — linking the issue above will provide helpful context.