Skip to content

fix: Reject connections whose current value the target refuses - #44

Merged
philippjfr merged 1 commit into
mainfrom
fix/untyped-connection-validation
Sep 28, 2026
Merged

philippjfr merged 1 commit into
mainfrom
fix/untyped-connection-validation

Conversation

@philippjfr

Copy link
Copy Markdown
Contributor

Description

I made connection validation reject an untyped output whose current value the target input would refuse, and made a connection whose first propagated value is refused roll back instead of staying wired. An output registered through provides without a type (as the built-in Select does) passed the static type check against any input, so the drag indicator showed a typed input such as param.Integer as valid; after the drop the first value failed in the target component, the error was only reported through on_error, and the edge stayed on the canvas and in the graph with the node state holding the rejected value.

  • InputPort now keeps the component's own parameter when ports are introspected from a Viewer class, and InputPort.check_value() runs that parameter's validation without assigning anything.
  • DataflowGraph.validate_connection checks the source's current value against the target input after the static checks, so drag validation marks the handle invalid with the parameter's reason, for example "Input 'start_year' rejects the current value of 'selected': Integer parameter 'app.start_year' must be an integer, not <class 'str'>."
  • DataflowGraph.add_edge now returns "Connection rejected: ..." when the initial propagation raises, removing the watcher and edge and restoring the target's previous value. This covers targets without an introspected parameter, and FlowDash already removes a rejected edge from the canvas.

Behavior change: a connection whose first value is rejected used to be kept and reported through on_error; it is now refused. Values that change after a connection is made are still reported through on_error, since their compatibility cannot be known in advance.

import panel as pn
import param
from panel.viewable import Viewer

from panel_flowdash import register
from panel_flowdash.editor import FlowDash

pn.extension()


@register(page=False, component=True, provides=[{"key": "picked"}])
class Picker(Viewer):
    value = param.Parameter(default="A")

    @param.output(param.Parameter)
    @param.depends("value")
    def picked(self):
        return self.value

    def __panel__(self):
        return str(self.value)


class YearRange(Viewer):
    start_year = param.Integer(default=2000)

    def __panel__(self):
        return str(self.start_year)


editor = FlowDash({"Demo/picker": Picker, "Demo/years": YearRange})
picker = editor.add_component("Demo/picker", position=(0, 0))
years = editor.add_component("Demo/years", position=(400, 0))
print(editor.connect(picker, "picked", years, "start_year"))
editor.servable()

Before, connect returned True, logged a runtime wiring error, and left the edge in place; dragging picked onto start_year showed the handle as valid. After, connect returns the rejection reason, and the drag marks start_year invalid with that reason as its tooltip.

I added test_initial_propagation_failure_rejects_connection (replacing test_error_on_initial_propagation, which asserted the old behavior), test_current_value_checked_against_input_parameter, test_unset_output_is_not_value_checked, test_untyped_output_with_rejected_value_is_refused, test_untyped_output_connects_once_its_value_fits, and the Playwright test test_editor_drag_validation_rejects_untyped_value_of_wrong_type. All but the last compatibility test fail on main. pixi run test (334 passed, 2 skipped), the UI suite (3 passed), and pre-commit pass.

AI Disclosure

Tool & Model: Kilo Code + Claude Opus 5.5
Usage: Diagnosed the report from the complex dataflow example, implemented the fix and tests, and drafted this description; I reviewed the diff and ran the listed checks.

  • I have tested all AI-generated content in my PR.
  • I take responsibility for all AI-generated content in my PR.

Checklist

  • Tests added and are passing

@philippjfr
philippjfr merged commit 2d66a0d into main Sep 28, 2026
14 checks passed
@philippjfr
philippjfr deleted the fix/untyped-connection-validation branch September 28, 2026 18:53
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.

1 participant