StackStorm/st2flow

Cannot delete parameter from Mistral action meta if only one parameter exists

Closed this issue · 1 comments

This appears to be a crawler error. When deleting parameters from Mistral workflows, the operation works as normal until deleting the last param. The following error is displayed in console:

crawler.js:158 Uncaught TypeError: Cannot set property 'prefix' of null
    at Object.replaceTokenValue (crawler.js:158)
    at Object.set (crawler.js:30)
    at MetaModel.set (base-class.js:94)
    at flowReducer (store.js:131)
    at reducer (store.js:383)
    at store.js:26
    at Array.forEach (<anonymous>)
    at rootReducer (store.js:26)
    at dispatch (createStore.js:178)
    at store.js:35

It appears that the crawler is not able to return a parent token with the value property properly set. When deleting not the last parameter, parentToken.value in crawler.replaceTokenValue() looks like:

{
  endPosition: 228
  jpath: (3) ["mappings", 2, "value"]
  kind: 2
  mappings: Array(2)
    0: {startPosition: 48, endPosition: 148, jpath: Array(5), range: Array(2), kind: 1, …}
    1: {startPosition: 148, endPosition: 228, jpath: Array(5), range: Array(2), kind: 1, …}
    length: 2
  range: Array(2)
    0: {row: 2, column: 10}
    1: {row: 13, column: 18}
    length: 2
  startPosition: 48
}

While when deleting the final one, parentToken.value gets created (via the factory creating a token from an empty object) to look like:

{
  endPosition: 0
  jpath: []
  kind: 2
  mappings: []
  range: Array(2)
    0: {row: 0, column: 0}
    1: {row: 0, column: 0}
  length: 2
  startPosition: 0
}

Without mappings there is no first value token (finding it returns null), so this sequence breaks:

        const newFirst = this.findFirstValueToken(parentToken.value);
        newFirst.prefix = oldFirst && oldFirst.prefix;

Either this operation should delete the key, or replacing the parent with an empty object should avoid attempting to set properties on the nonexistent new first value token.

I didn't look deep enough into this but I suspect that prefix here is for meaningful comments. Be careful not to break features that depend on the comments (placement and color) if fixing at the crawler level.

Note, the code in crawler.js now looks like:

        const newFirst = this.findFirstValueToken(parentToken.value);
        if(oldFirst) {
          newFirst.prefix = oldFirst.prefix;
        }

Likely the correct fix is to do if(newFirst && oldFirst) {