Skip to content

add_node accepts non-JSON-safe config; failure deferred to fingerprint time #217

Description

@duncanita

Severity: low
Found in: 2026-07-22 code review

Location

lib/dag/workflow/definition.rb:40-47, lib/dag/workflow/definition/builder.rb:27-34; contrast with lib/dag/graph.rb:74 where edge metadata is eagerly checked via DAG.json_safe!.

Failure mode

The documented contract is "config [Hash] JSON-safe step config" (configs flow into to_h and therefore into the fingerprint port), but neither add_node path validates it. A config like {when: Time.now} is accepted, deep-frozen, and can even be durably stored by Memory::Storage; it only explodes later when the definition is fingerprinted (Stdlib::FingerprintArgumentError: non JSON-safe value at $root.nodes[0].config.when) or serialized by a durable adapter. Boundary-validation inconsistency: edge metadata fails fast at the exact call site, node config does not.

Minimal trigger (verified)

DAG::Workflow::Definition.new.add_node(:a, type: :noop, config: {when: Time.now}) succeeds; .fingerprint(via: DAG::Adapters::Stdlib::Fingerprint.new) raises ArgumentError.

Fix direction

Call DAG.json_safe! on config: in both add_node paths, matching the edge-metadata behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions