HTTP node key-value storage: three bugs share one root cause (in-band delimiters in a joined string) — worth a structured model? #39567
dparkmit24
started this conversation in
Suggestion
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Self Checks
1. Is this request related to a challenge you're experiencing? Tell me about your story.
Working in the HTTP Request node's Params / Headers / body tables, I've hit three separate defects that all trace back to one thing: this key-value data is persisted as a single newline-joined, colon-delimited string (
key:value\nkey:value), and the editor round-trips list → string → list on every edit. In-band delimiters (\nbetween rows,:between key and value) plus no stable per-row identity is a combination that keeps producing corruption bugs on different surfaces.Three bugs, one root cause:
Typing into the trailing row destroys it — fix: typing into the trailing Params/Headers row in the HTTP node no longer destroys the row #39552 (fixed). Each keystroke re-derived the list from the string and reassigned every row's id, remounting the editor mid-keystroke.
Enter corrupts the row; no keyboard advance — fix(http): stop Enter from corrupting Params/Headers rows; support Enter/Tab to advance #39566 (open). Pressing Enter in a key or value field inserts a literal newline, which the parser reads as a new row boundary, so a value typed before Enter is re-read as the next row's key. There's also no keyboard way to commit a row and advance to the next one.
Form-data body values are truncated at the first colon — HTTP node form-data body values are truncated at the first colon after reload #38860, with an open fix in fix: keep colons in HTTP node form body values on migration #38861 (not mine).
transformToBodyPayloadsplits each line on:and keeps only the first segment, sohttps://host:8080/pathbecomeshttps. This is the body path specifically — header/param values already survive colons viaothers.join(':')— but it's the same in-band-delimiter class biting a different field.So the header/param surface loses empty/half-typed rows, colons in a key, embedded newlines, and surrounding whitespace; the body surface additionally hard-truncates values at the first colon. Each has a narrow fix, but they're facets of one design choice.
2. Additional context or comments
The question: would you be open to moving this key-value data from the joined string to a structured
{ key, value, id }[]list with a stable per-row id? That would make these classes structurally impossible rather than individually patched, and give rows a stable identity so the editor doesn't remount on round-trip.To sanity-check feasibility before raising it, I prototyped the frontend change on a branch (happy to share or open a PR if you're interested). What that prototype found:
{key,value,id}[]list — the string only exists at the save boundary — so the frontend change is ~100 lines of conversion code plus a rewritten hook. TypeScript over the wholewebworkspace confirms only four call sites read these fields as strings.app/components/workflowtest suite (3139 tests) still passes with the change.string | BodyPayloadon both sides, with a Pydanticbeforevalidator handling the legacy string form. A headers/params migration would follow that precedent one-for-one.What I did not establish, because it's where the real cost is:
graphonpackage, whereheaders/paramsare typedstr— a structured list would fail validation today. This cannot ship frontend-only; it needs a coordinatedgraphonrelease + version bump. That's the main thing I'd want your read on.Open questions for you:
graphon+difyrelease for this, and what's the process/appetite?body.dataprecedent) sufficient on its own?body.datadoes today), or a one-time write migration of stored workflows?If you'd rather keep the string model and just take the narrow per-bug fixes, that's completely reasonable — I mainly wanted to surface that these aren't three unrelated bugs, and that the structural alternative looks tractable on the frontend with a known-precedent backend path.
3. Can you help us with this feature?
All reactions