Summary
DaVinciFlowGraphDataResponseElementsNodeData (and its request counterpart) has no field for a DaVinci flow node's outcomes — the array that defines a node's named exit paths (e.g. a form's "Save" vs. "Resend" buttons). The gap originates in the SDK's own OpenAPI spec, not just the generated Go structs, so it can't be fixed by regenerating from the current spec — the spec itself needs the property added.
This causes a real, reproducible bug downstream: terraform-provider-pingone's pingone_davinci_flow resource generates its schema from this SDK, so it also has no way to read or write outcomes on node data. Edges reference a specific outcome by ID via multiValueSourceId (which round-trips correctly today). When a flow with multi-outcome nodes is read via the SDK, re-exported, and re-applied, the outcome definitions are silently dropped while the edges referencing their IDs are preserved — producing a flow with edges that point at outcome IDs that no longer exist on any node. The flow renders broken in the DaVinci UI. Filing this against terraform-provider-pingone as well: [link/cross-reference once filed].
Reproduction
Given a flow node like this one from a live PingOne environment (a pingOneFormsConnector showForm node with two named outcomes):
{
"id": "esqd1w6k6h",
"nodeType": "CONNECTION",
"capabilityClass": "render",
"capabilityName": "showForm",
"connectorId": "pingOneFormsConnector",
"outcomes": [
{ "result": "submit", "label": "Save", "id": "0qw160q8zo" },
{ "result": "resend", "label": "Didn't receive an email? Resend", "id": "k0hv0wr75q" }
]
}
Two edges elsewhere in the same flow route based on those outcome IDs:
{ "source": "esqd1w6k6h", "target": "vzo75y0cg1", "multiValueSourceId": "0qw160q8zo" }
{ "source": "esqd1w6k6h", "target": "vzo75y0cg1", "multiValueSourceId": "k0hv0wr75q" }
resp, _, err := apiClient.DaVinciFlowsApi.GetFlowById(ctx, environmentID, flowID).Execute()
node := resp.GraphData.Elements.Nodes[/* the showForm node */]
node.Data.Outcomes // does not exist — compile error; the only way to access this is
// node.Data.AdditionalProperties["outcomes"], as an untyped interface{}
outcomes lands in NodeData.AdditionalProperties["outcomes"] as an untyped interface{} (a []interface{} of map[string]interface{}), because the field isn't declared in the OpenAPI spec at all — confirmed by grepping pingone/api/openapi.yaml for outcome (case-insensitive) with zero matches, at the current main HEAD (2d5939c0, = v0.11.0).
Root cause
The OpenAPI spec's DaVinciFlowGraphDataResponse schema (and the parallel ...Request schema) enumerates node data properties explicitly:
elements:
nodes:
- data:
capabilityName: capabilityName
connectorId: connectorId
label: label
nodeType: nodeType
type: type
linterError: [...]
name: name
connectionId: connectionId
idUnique: idUnique
id: id
capabilityClass: capabilityClass
properties: {...}
status: status
outcomes is absent from this list. Because the generated Go structs (model_da_vinci_flow_graph_data_response_elements_node_data.go, model_da_vinci_flow_graph_data_request_elements_node_data.go) are produced directly from this spec, they only have a typed field for each enumerated property, plus a generic AdditionalProperties map[string]interface{} catch-all for anything else. outcomes falls into that catch-all.
The catch-all does round-trip through MarshalJSON/UnmarshalJSON today (values in AdditionalProperties are re-serialized on marshal), so raw pass-through consumers of the SDK aren't silently losing data at the SDK layer by themselves. The actual breakage happens one layer up: consumers that build typed request objects from a Terraform-style intermediate representation (e.g. terraform-provider-pingone, or pingcli-plugin-terraformer's export/reflection pipeline) have no typed field to map to/from, and their own generated schemas — themselves generated from this SDK — have no attribute for outcomes either. The result is that outcomes never survives a read → external representation → write round-trip in any of the tooling built on top of this SDK.
Suggested fix
Add outcomes to the OpenAPI spec's node data schema (both DaVinciFlowGraphDataResponse and DaVinciFlowGraphDataRequest node data definitions) as an array of objects with:
id (string, required) — client-assigned; consumers depend on this being preserved verbatim since edges reference it via multiValueSourceId
result (string) — the internal outcome key (e.g. submit, resend)
label (string) — the user-facing label (e.g. "Save", "Didn't receive an email? Resend")
Regenerate the SDK from the updated spec so NodeData.Outcomes becomes a typed field. outcomes is conditional — most nodes don't have it (only certain render capabilities with multiple exit paths, based on observation), so it should be optional/omitempty like the other node data fields.
Environment
- SDK version:
github.com/pingidentity/pingone-go-client v0.11.0 (confirmed still current — this is the tip of main as of this report)
- Also reproduced against v0.10.1 (the version
terraform-provider-pingone currently pins) and all other cached versions back to v0.2.0 — the gap has existed throughout
- Downstream impact confirmed in
terraform-provider-pingone's generated pingone_davinci_flow schema (internal/service/davinci/resource_davinci_flow_gen.go), and in pingcli-plugin-terraformer's export pipeline
Summary
DaVinciFlowGraphDataResponseElementsNodeData(and its request counterpart) has no field for a DaVinci flow node'soutcomes— the array that defines a node's named exit paths (e.g. a form's "Save" vs. "Resend" buttons). The gap originates in the SDK's own OpenAPI spec, not just the generated Go structs, so it can't be fixed by regenerating from the current spec — the spec itself needs the property added.This causes a real, reproducible bug downstream:
terraform-provider-pingone'spingone_davinci_flowresource generates its schema from this SDK, so it also has no way to read or writeoutcomeson node data. Edges reference a specific outcome by ID viamultiValueSourceId(which round-trips correctly today). When a flow with multi-outcome nodes is read via the SDK, re-exported, and re-applied, the outcome definitions are silently dropped while the edges referencing their IDs are preserved — producing a flow with edges that point at outcome IDs that no longer exist on any node. The flow renders broken in the DaVinci UI. Filing this againstterraform-provider-pingoneas well: [link/cross-reference once filed].Reproduction
Given a flow node like this one from a live PingOne environment (a
pingOneFormsConnectorshowFormnode with two named outcomes):{ "id": "esqd1w6k6h", "nodeType": "CONNECTION", "capabilityClass": "render", "capabilityName": "showForm", "connectorId": "pingOneFormsConnector", "outcomes": [ { "result": "submit", "label": "Save", "id": "0qw160q8zo" }, { "result": "resend", "label": "Didn't receive an email? Resend", "id": "k0hv0wr75q" } ] }Two edges elsewhere in the same flow route based on those outcome IDs:
{ "source": "esqd1w6k6h", "target": "vzo75y0cg1", "multiValueSourceId": "0qw160q8zo" } { "source": "esqd1w6k6h", "target": "vzo75y0cg1", "multiValueSourceId": "k0hv0wr75q" }outcomeslands inNodeData.AdditionalProperties["outcomes"]as an untypedinterface{}(a[]interface{}ofmap[string]interface{}), because the field isn't declared in the OpenAPI spec at all — confirmed by greppingpingone/api/openapi.yamlforoutcome(case-insensitive) with zero matches, at the currentmainHEAD (2d5939c0, =v0.11.0).Root cause
The OpenAPI spec's
DaVinciFlowGraphDataResponseschema (and the parallel...Requestschema) enumerates node data properties explicitly:outcomesis absent from this list. Because the generated Go structs (model_da_vinci_flow_graph_data_response_elements_node_data.go,model_da_vinci_flow_graph_data_request_elements_node_data.go) are produced directly from this spec, they only have a typed field for each enumerated property, plus a genericAdditionalProperties map[string]interface{}catch-all for anything else.outcomesfalls into that catch-all.The catch-all does round-trip through
MarshalJSON/UnmarshalJSONtoday (values inAdditionalPropertiesare re-serialized on marshal), so raw pass-through consumers of the SDK aren't silently losing data at the SDK layer by themselves. The actual breakage happens one layer up: consumers that build typed request objects from a Terraform-style intermediate representation (e.g.terraform-provider-pingone, orpingcli-plugin-terraformer's export/reflection pipeline) have no typed field to map to/from, and their own generated schemas — themselves generated from this SDK — have no attribute foroutcomeseither. The result is thatoutcomesnever survives a read → external representation → write round-trip in any of the tooling built on top of this SDK.Suggested fix
Add
outcomesto the OpenAPI spec's node data schema (bothDaVinciFlowGraphDataResponseandDaVinciFlowGraphDataRequestnode data definitions) as an array of objects with:id(string, required) — client-assigned; consumers depend on this being preserved verbatim since edges reference it viamultiValueSourceIdresult(string) — the internal outcome key (e.g.submit,resend)label(string) — the user-facing label (e.g. "Save", "Didn't receive an email? Resend")Regenerate the SDK from the updated spec so
NodeData.Outcomesbecomes a typed field.outcomesis conditional — most nodes don't have it (only certain render capabilities with multiple exit paths, based on observation), so it should be optional/omitempty like the other node data fields.Environment
github.com/pingidentity/pingone-go-client v0.11.0(confirmed still current — this is the tip ofmainas of this report)terraform-provider-pingonecurrently pins) and all other cached versions back to v0.2.0 — the gap has existed throughoutterraform-provider-pingone's generatedpingone_davinci_flowschema (internal/service/davinci/resource_davinci_flow_gen.go), and inpingcli-plugin-terraformer's export pipeline