Skip to content

fix: nil-safe bracket access in propertyAccessSeq + nil-safe downcase filter#45

Draft
sd-gh-bot wants to merge 1 commit into
masterfrom
fix/scope-bracket-access-nil-variable-crash
Draft

fix: nil-safe bracket access in propertyAccessSeq + nil-safe downcase filter#45
sd-gh-bot wants to merge 1 commit into
masterfrom
fix/scope-bracket-access-nil-variable-crash

Conversation

@sd-gh-bot

@sd-gh-bot sd-gh-bot commented Jun 15, 2026

Copy link
Copy Markdown

User description

Problem

Customer Wingify/VWO (wsid=3409, cluster=IN) is unable to create contracts using Workflow 1401 (Order Form - Template workflow). Every attempt produces a ComputationError in the cfexporter BlanksGenerator.

Sentry: https://spotdraft.sentry.io/issues/6765108933/events/827b3b17706642af8ca9bf4f55500326/

Root Cause

Two bugs in LiquidJS fired when a computed field for the sd_order_details dynamic table (field sd_unit) uses bracket notation unit_mapping[self.sd_product] outside a {% computeColumn %} wrapper:

Bug 1 — src/scope.jspropertyAccessSeq crashes on nil bracket variable

When self is not in scope, this.get('self.sd_product') returns undefined (the error is swallowed because strict_variables=false). The inner name is set to undefined, and then push() executes if (name.length)TypeError: Cannot read properties of undefined (reading 'length').

Fix: Coerce the nil result to an empty string before calling push(). An empty name is safely skipped.

Bug 2 — filters.jsdowncase crashes on nil input

The fork's downcase was v => v.toLowerCase(). When v is undefined (from a nil Liquid variable), this crashes: TypeError: Cannot read properties of undefined (reading 'toLowerCase').

Fix: Guard with null check, returning "" for nil input.

Template fix (CSM action needed)

The sd_order_details computed fields (sd_ap, sd_cp, sd_unit) in Workflow 1401 are missing {% computeColumn %} wrappers. Without the wrapper, self is never bound per-row. The CSM should wrap each computed field's expression:

{% computeColumn sd_order_details sd_unit %}
  {% parseAssign unit_mapping = '...' %}
  {% assign $$answer = unit_mapping[self.sd_product] %}
  ...
{% endcomputeColumn %}

Tests

  • 2 new regression tests added to test/scope.js
  • 854 passing, 23 failing (23 failures are pre-existing, unrelated to this PR)

Affected workspace

  • wsid: 3409 (Wingify Software / VWO), cluster: IN
  • Workflow ID: 1401

Generated description

Below is a concise technical summary of the changes proposed in this PR:
Add nil-safe handling in Scope.propertyAccessSeq and push so bracket notation with undefined variables no longer throws and resolves to parent objects, matching Liquid semantics for Workflow computed fields. Guard downcase to return an empty string when input is nil and add regression tests covering undefined bracket variables in test/scope.js.

TopicDetails
Bracket guard path Ensure bracket access handles undefined variables by normalizing nil names before push so sequences resolve to parent paths and regression tests cover undefined bracket input.
Modified files (2)
  • src/scope.js
  • test/scope.js
Latest Contributors(2)
UserCommitDate
neo@spotdraft.comfix: nil-safe bracket ...June 15, 2026
harttle@harttle.comchange: remove depreca...December 23, 2017
Downcase guard Guard downcase to return an empty string when input is nil to avoid toLowerCase errors.
Modified files (1)
  • filters.js
Latest Contributors(2)
UserCommitDate
neo@spotdraft.comfix: nil-safe bracket ...June 15, 2026
parth-sd[SPD-23149] Add filter...July 05, 2024
Review this PR on Baz | Customize your next review

… filter

Two related bugs causing ComputationError when Liquid computation templates
use bracket notation (e.g. unit_mapping[self.sd_product]) outside a
computeColumn block, so that the bracket variable resolves to nil.

Bug 1 (src/scope.js — propertyAccessSeq):
  When this.get(name) returns undefined (strict_variables=false swallows
  'undefined variable' error), the local  variable is set to undefined.
  The inner push() helper then crashes:  throws
  'Cannot read properties of undefined (reading "length")'.
  Fix: coerce nil result to empty string before push(); empty name is safely
  skipped by push(), preventing the crash.

Bug 2 (filters.js — downcase):
  downcase was defined as v => v.toLowerCase(). When v is nil/undefined
  (e.g. self.sd_product when self is not in scope) this crashes with
  'Cannot read properties of undefined (reading "toLowerCase")'.
  Fix: guard with null check, returning empty string for nil input.

Root template issue (addressed separately by CSM):
  The sd_order_details computed fields (sd_ap, sd_cp, sd_unit) in Workflow
  1401, Workspace 3409 (Wingify/VWO) are missing {% computeColumn %} wrappers.
  Without the wrapper, self is never set per-row, making self.sd_product nil.
  All three computed fields should be wrapped in:
    {% computeColumn sd_order_details FIELD_NAME %}...{% endcomputeColumn %}

Fixes: VWO/Wingify wsid=3409 workflow_id=1401 contract creation failure
Sentry: 6765108933

Co-authored-by: Anusree Raj LS <anusree@spotdraft.com>
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.

1 participant