Skip to content

fix: typing into the trailing Params/Headers row in the HTTP node no longer destroys the row - #39552

Open
dparkmit24 wants to merge 2 commits into
langgenius:mainfrom
dparkmit24:fix-http-params-row-lifecycle
Open

fix: typing into the trailing Params/Headers row in the HTTP node no longer destroys the row#39552
dparkmit24 wants to merge 2 commits into
langgenius:mainfrom
dparkmit24:fix-http-params-row-lifecycle

Conversation

@dparkmit24

Copy link
Copy Markdown
Contributor

Summary

Fixes #39551.

In the HTTP Request node's Params and Headers key/value tables, typing any non-space character into the trailing (uncommitted) row destroyed the entire row — both the just-typed value and any key already entered. Values could only be entered by pasting.

Root cause: params/headers are stored as a newline-joined string, and every change round-trips list → string → list. Two mechanisms in the shared use-key-value-list.ts hook combined to drop input:

  1. A microtask useEffect re-derived the list from the string on each change and reassigned every row's id, remounting the Lexical editor mid-keystroke and dropping the character being typed.
  2. The add-row handler closed over a stale list, so an onChange immediately followed by an onAdd let the add overwrite the value that was just typed.

Fix: hold a listRef mirror so the add path no longer closes over a stale list, and preserve ids for rows that already exist — only assigning a new id to a genuinely new row — so the editor is no longer remounted on every keystroke. Both tables share the hook, so this fixes Params and Headers together. The newline-joined-string storage model is left unchanged (deliberately out of scope for this fix).

Test: added a regression test in the existing Vitest suite that mounts the key-value editor, types into the trailing row's value, and asserts the row survives with its key and value intact. It fails on current main and passes with this change; the full workflow-nodes suite and tsc --noEmit stay green.

Not addressed here: pressing Enter in the trailing row's key field still migrates the existing value into the newly-created row. That stems from the same newline-joined-string storage model and would require changing it, so it's left as a documented follow-up in #39551.

Screenshots

Before
Typing open into the trailing Params value row on main — the row is destroyed on the first character, losing both the key and the value.

2026-07-24_13-36-31.mp4

After
Same sequence with the fix — the row survives, key and value are preserved, and a new empty row appears as expected.

2026-07-24_15-33-28.mp4

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint && make type-check (backend) and cd web && pnpm exec vp staged (frontend) to appease the lint gods

From Claude Code

The HTTP Request node stores Params/Headers as a newline-joined `key:value`
string; `useKeyValueList` round-trips list→string→list on every change. Two
issues in that hook destroyed the trailing (uncommitted) row when a user typed
the first character into its Value field:

1. `addItem` closed over the render-time `list`, so the `onChange`+`onAdd`
   pair that fires on the first value keystroke let `onAdd` append to a stale
   list and overwrite the just-typed value.
2. The microtask effect re-derived the list from the string and reassigned a
   fresh `id` to every row, remounting the Lexical editor mid-keystroke.

Fix (narrow, storage model unchanged):
- Keep a `listRef` mirror updated synchronously in `commitList` so `addItem`
  appends to the latest list, not a stale closure.
- Preserve existing rows' ids (positional match) when the effect reconciles
  from the string, so stable rows are not remounted.

Both Params and Headers share this hook and are fixed by the one change.

Adds a happy-dom regression test that mounts the real key/value editor (Lexical
leaf stubbed) and asserts the trailing row survives a keystroke without the
editor remounting. Fails before this change, passes after.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jul 24, 2026
@github-actions github-actions Bot added the web This relates to changes on the web. label Jul 24, 2026
@dparkmit24

dparkmit24 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Scope note: use-key-value-list.ts and the key-value editor it feeds are imported only by the HTTP Request node — driving both the Params and Headers tables, which is why this one change fixes both. No other panel uses this hook or editor. The other key/value tables in the workflow editor use a different, unaffected model (the Webhook trigger's tables are array-based; the variable list is an array of Variable[]; paragraph input is a plain textarea). The HTTP node's form-data body is also string-based but is a separate, pre-existing defect (#38860), reload-time colon truncation), untouched by this change.

@dparkmit24

dparkmit24 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@crazywoola: The linked issue #39551 was erroneously closed when #38861 merged. That PR changes transformToBodyPayload so colons are kept in form-data body values, which doesn't fix the defect in #39551. Could you reopen #39551 and take a look at this PR?

The defect in #39551 is a different one on the Params/Headers tables: typing any non-space character into the trailing row destroys the row, because each keystroke re-derives the list and reassigns every row's id, remounting the Lexical editor mid-keystroke. It's a remount-on-keystroke problem rather than a parsing one, and #38861's change doesn't touch it. Re-checked against current main — still reproduces, 5/5, and pasting still works where typing doesn't.

This PR carries that fix with its regression test. Happy to rebase if useful.

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

Labels

size:M This PR changes 30-99 lines, ignoring generated files. web This relates to changes on the web.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTTP Request node: typing into the trailing Params/Headers row destroys the row

1 participant