Skip to content

fix: process.export broken when state and parameters not explicitly provided#226

Open
Copilot wants to merge 2 commits intomainfrom
copilot/fix-process-export-bug
Open

fix: process.export broken when state and parameters not explicitly provided#226
Copilot wants to merge 2 commits intomainfrom
copilot/fix-process-export-bug

Conversation

Copy link
Contributor

Copilot AI commented Mar 9, 2026

process.dump() fails with a Pydantic validation error when state and parameters are omitted at LocalProcess construction.

Root cause: ExportMixin._save_args_wrapper wraps both LocalProcess.__init__ and Process.__init__. When LocalProcess.__init__ calls super().__init__(..., parameters=None, state=None), the parent wrapper captures those explicit None values and merges them into __save_args_init__. The export dict then contains parameters=None and state=None, which fail ProcessArgsSpec validation.

# This was broken:
process = LocalProcess(components=[A(), B()], connectors=[...])
process.dump("out.yaml")  # ValidationError: state=None, parameters=None

Changes

  • plugboard-schemas/plugboard_schemas/process.py: Added _coerce_parameters and _coerce_state field_validators to ProcessArgsSpec to coerce None{} and NoneStateBackendSpec() respectively. Consistent with ProcessArgsDict which already typed state as NotRequired[StateBackendSpec | None].
  • tests/integration/test_process_builder.py: Added test_process_dump_with_default_state_and_parameters to reproduce and validate the fix.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • astral.sh
    • Triggering command: /usr/bin/curl curl -LsSf REDACTED grep -l state.*None py de/node/bin/grep (dns block)
  • releases.astral.sh
    • Triggering command: /home/REDACTED/.local/bin/uv uv venv .venv --python python3.13 state.*None hemas/state.py k/_temp/ghcca-node/node/bin/grep (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>bug: process.export broken</issue_title>
<issue_description>### Summary

Consider this model:

from plugboard.component import Component, IOController as IO
from plugboard.process import LocalProcess
from plugboard.connector import AsyncioConnector
from plugboard.schemas import ConnectorSpec

class A(Component):
    io = IO(outputs=["out_1"])

    async def step(self) -> None:
        pass

class B(Component):
    io = IO(inputs=["in_1"])

    async def step(self) -> None:
        pass

process.dump("test-export.yaml")

Fails with:

  Input should be a valid dictionary [type=dict_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.12/v/dict_type
plugboard.process.args.state
  Input should be a valid dictionary or instance of StateBackendSpec [type=model_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.12/v/model_type

Version Information

Plugboard version: 0.6.0
Platform: Linux-6.6.84.1-microsoft-standard-WSL2-x86_64-with-glibc2.39
Python version: 3.12.11
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix broken process.export function in plugboard fix: process.export broken when state and parameters not explicitly provided Mar 9, 2026
@toby-coleman toby-coleman marked this pull request as ready for review March 9, 2026 13:11
@github-actions
Copy link

github-actions bot commented Mar 9, 2026

Benchmark comparison for 64adfa9a (base) vs 92eccec1 (PR)


------------------------------------------------------------------------------------------------------------------ benchmark: 2 tests -----------------------------------------------------------------------------------------------------------------
Name (time in ms)                                                                         Min                 Max                Mean            StdDev              Median               IQR            Outliers     OPS            Rounds  Iterations
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_benchmark_process_run (pr/.benchmarks/Linux-CPython-3.12-64bit/0001_pr)         363.9104 (1.0)      376.8133 (1.01)     367.8705 (1.0)      5.1566 (4.24)     365.9110 (1.0)      4.8327 (2.49)          1;0  2.7183 (1.0)           5           1
test_benchmark_process_run (main/.benchmarks/Linux-CPython-3.12-64bit/0001_base)     370.3269 (1.02)     373.1919 (1.0)      371.3854 (1.01)     1.2172 (1.0)      370.9975 (1.01)     1.9383 (1.0)           1;0  2.6926 (0.99)          5           1
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean

@codecov
Copy link

codecov bot commented Mar 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: process.export broken

2 participants