Skip to content

Fixed collection variable sync on cloud for empty row#4475

Merged
rohitneharabrowserstack merged 11 commits intomasterfrom
RQ-659_fix_collection_var
Mar 13, 2026
Merged

Fixed collection variable sync on cloud for empty row#4475
rohitneharabrowserstack merged 11 commits intomasterfrom
RQ-659_fix_collection_var

Conversation

@rohitneharabrowserstack
Copy link
Contributor

@rohitneharabrowserstack rohitneharabrowserstack commented Mar 5, 2026

Closes issue:

📜 Summary of changes:

🎥 Demo Video:

Video/Demo:

✅ Checklist:

  • Make sure linting and unit tests pass.
  • No install/build warnings introduced.
  • Verified UI in browser.
  • For UI changes, added/updated analytics events (if applicable).
  • For changes in extension's code, manually tested in Chrome and Firefox.
  • Added/updated unit tests for this change.
  • Raised pull request to update corresponding documentation (if already exists).
  • Added demo video showing the changes in action (if applicable).

🧪 Test instructions:

🔗 Other references:

Summary by CodeRabbit

  • Bug Fixes
    • Fixed saving of collection variables in API records: keys are trimmed, empty keys are excluded, local-only values are removed, and variable ordering is reconciled with the remaining keys. This prevents stale or empty entries from persisting and ensures consistent variable maps when updating records.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Sanitization for COLLECTION records was changed: when building the variables map each entry's map key and the variable's key are both trimmed and the non-empty result is used as the final key; entries with an empty final key are dropped. The localValue field is removed from variables. The variables map construction excludes any non-pair results. If variablesOrder exists it is trimmed and filtered to include only keys present in the sanitized variables.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • nafees87n
🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description consists entirely of the template with no actual content filled in; all required sections (issue link, summary, demo, test instructions) are empty or contain only placeholder comments. Fill in the description template with the actual issue link, a summary of the changes made, test instructions, and explain why demo video is not applicable if applicable.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing collection variable synchronization on cloud for empty rows, which aligns with the code modifications in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch RQ-659_fix_collection_var
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/backend/apiClient/upsertApiRecord.ts`:
- Around line 27-40: The map over sanitizedRecord.data.variables can destructure
a null/undefined variable causing a TypeError; in the map callback that computes
entryKeyTrimmed/valueKeyTrimmed/finalKey and then does const { localValue, key:
_ignored, ...rest } = variable, first guard that variable is truthy (e.g., if
(!variable) return null) or replace with a safe default before destructuring
(e.g., const v = variable ?? {}; then destructure v) so you never destructure
null/undefined; ensure the callback still returns null for skipped entries so
the subsequent .filter((pair): pair is [string, any] => Array.isArray(pair))
continues to work.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b9bde200-870f-4960-a39f-bed3a619f22b

📥 Commits

Reviewing files that changed from the base of the PR and between b0d2939 and 1870470.

📒 Files selected for processing (1)
  • app/src/backend/apiClient/upsertApiRecord.ts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
app/src/backend/apiClient/upsertApiRecord.ts (2)

32-34: Minor: Redundant optional chaining.

On line 33, variable?.key uses optional chaining, but variable is already guaranteed to be truthy due to the guard at lines 29-31. This is harmless but slightly redundant.

-              const valueKeyTrimmed = (variable?.key || "").toString().trim();
+              const valueKeyTrimmed = (variable.key || "").toString().trim();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/backend/apiClient/upsertApiRecord.ts` around lines 32 - 34, The
optional chaining in the expression used to build valueKeyTrimmed is redundant
because variable is already guaranteed truthy by the earlier guard; replace
variable?.key with variable.key when computing valueKeyTrimmed (the lines
computing entryKeyTrimmed, valueKeyTrimmed, and finalKey) so the code reads
valueKeyTrimmed = (variable.key || "").toString().trim() and keep finalKey =
entryKeyTrimmed || valueKeyTrimmed unchanged.

46-50: Potential order loss when empty entry keys are normalized to variable.key.

When an entry has an empty entryKey but a non-empty variable.key, the sanitized variables map uses valueKeyTrimmed as the finalKey. However, variablesOrder still contains the original empty key, which gets filtered out here (empty string is falsy). This causes the renamed variable to lose its position in the order.

Example scenario:

  • Original: entryKey = "", variable.key = "myVar", variablesOrder = ["", "other"]
  • After sanitization: variables = { "myVar": {...} }, variablesOrder = ["other"]
  • Result: "myVar" is orphaned from the order

The downstream mapToEnvironmentArray (in environment/utils.ts) appends unordered keys at the end, so data isn't lost, but the variable's original position is not preserved. If this is acceptable for the empty-row edge case, consider adding a brief comment explaining the behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/backend/apiClient/upsertApiRecord.ts` around lines 46 - 50, The
current filter removes falsy/empty entries from
sanitizedRecord.data.variablesOrder which drops variables that were renamed from
an empty entryKey (e.g., entryKey = "" -> variable.key = "myVar"), losing their
original position; update the variablesOrder normalization so that for each
entry you trim k, and if the trimmed key is empty but there exists a variable in
sanitizedRecord.data.variables whose original entryKey was falsy (or whose
valueKeyTrimmed/variable.key was used as the final key) then replace the empty
slot with that variable's final key instead of filtering it out; implement this
by mapping sanitizedRecord.data.variablesOrder to trimmed keys, and when
encountering a falsy trimmed key, find the next unused variable in
sanitizedRecord.data.variables with an original/falsy entryKey (or matching
valueKeyTrimmed) and insert its final key, leaving other keys unchanged so
original ordering is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/backend/apiClient/upsertApiRecord.ts`:
- Around line 32-34: The optional chaining in the expression used to build
valueKeyTrimmed is redundant because variable is already guaranteed truthy by
the earlier guard; replace variable?.key with variable.key when computing
valueKeyTrimmed (the lines computing entryKeyTrimmed, valueKeyTrimmed, and
finalKey) so the code reads valueKeyTrimmed = (variable.key ||
"").toString().trim() and keep finalKey = entryKeyTrimmed || valueKeyTrimmed
unchanged.
- Around line 46-50: The current filter removes falsy/empty entries from
sanitizedRecord.data.variablesOrder which drops variables that were renamed from
an empty entryKey (e.g., entryKey = "" -> variable.key = "myVar"), losing their
original position; update the variablesOrder normalization so that for each
entry you trim k, and if the trimmed key is empty but there exists a variable in
sanitizedRecord.data.variables whose original entryKey was falsy (or whose
valueKeyTrimmed/variable.key was used as the final key) then replace the empty
slot with that variable's final key instead of filtering it out; implement this
by mapping sanitizedRecord.data.variablesOrder to trimmed keys, and when
encountering a falsy trimmed key, find the next unused variable in
sanitizedRecord.data.variables with an original/falsy entryKey (or matching
valueKeyTrimmed) and insert its final key, leaving other keys unchanged so
original ordering is preserved.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d96419fd-fb39-4384-b4de-90dc72be115f

📥 Commits

Reviewing files that changed from the base of the PR and between 1870470 and 58c21fe.

📒 Files selected for processing (1)
  • app/src/backend/apiClient/upsertApiRecord.ts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/backend/apiClient/upsertApiRecord.ts`:
- Around line 46-49: The trimmed variablesOrder entries can collapse into
duplicates (e.g. " foo " -> "foo") and cause duplicate rendering; update the
sanitization in upsertApiRecord by deduplicating the normalized keys after
trimming/filtering: transform sanitizedRecord.data.variablesOrder with .map(k =>
(k||'').trim()).filter(k => k && sanitizedRecord.data?.variables[k]) then remove
duplicates while preserving order (e.g., using a Set or seen map) so
mapToEnvironmentArray() receives a unique, trimmed variablesOrder array; ensure
the final value remains an array on sanitizedRecord.data.variablesOrder.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f6864068-044d-4e99-a4d0-4bde267fc303

📥 Commits

Reviewing files that changed from the base of the PR and between b597f63 and a9dde2b.

📒 Files selected for processing (1)
  • app/src/backend/apiClient/upsertApiRecord.ts

return null; // will be filtered out
}

const { localValue, key: _ignored, ...rest } = variable;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still get this key in the object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we do get it

@rohitneharabrowserstack rohitneharabrowserstack merged commit 87baa56 into master Mar 13, 2026
3 checks passed
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.

2 participants