Built something you're proud of? Tell the story. A quick G2 review of App Engine or Build Agent helps other developers see what's possible on ServiceNow. Share your experience.

Error when doing the test run

Its_Azar
Mega Sage

Hi all, 

 

i have built an sub flow where it fetched the details of the control record the input is the number of the control. its working fine but when i created a custom skill and added the subflow in tool, the test run is not working i mean its not even doing the lookup on the table, attached screenshots.

 

Observations: when i call the input of my skill in tool (subflow) input, the response im getting is like below: 

Its_Azar_0-1775864525653.png

it should be just number not sure why this input is being sent along, any help is appreciated.

 

Its_Azar_0-1775853148723.pngIts_Azar_1-1775853223549.pngIts_Azar_2-1775853342022.png

 

 

☑️ If this helped, please mark it as Helpful or Accept Solution so others can find the answer too.

Kind Regards,
Azar
Serivenow Rising Star
Developer @ KPMG.

2 ACCEPTED SOLUTIONS

Naveen20
ServiceNow Employee

Add a Script step in the subflow before the Look Up Record action, parse out the actual number, set it into a flow variable, and use that variable in the Look Up Record.

Here's the walkthrough:

Step 1 — Create a new flow variable

Open your subflow, go to the flow variables section, and create a new variable:

  • Name: parsed_control_number
  • Type: String

Step 2 — Add a Script step

Add a Script Step (Flow Logic → Script) as the very first action in your subflow, before the Look Up Record. Use this script:

(function execute(inputs, outputs) {

    var raw = inputs.control_number; // your subflow input variable name

    if (raw) {
        raw = raw.toString().trim();

        // If AI Agent Studio wrapped it in JSON, extract the value
        if (raw.indexOf('{') === 0) {
            try {
                var parsed = JSON.parse(raw);
                raw = parsed.input || parsed.number || '';
            } catch (e) {
                // Not valid JSON, use as-is
            }
        }

        // Strip any extra quotes that may remain
        raw = raw.replace(/^"|"$/g, '');
    }

    outputs.parsed_number = raw || '';

})(inputs, outputs);

In the Script step configuration, map the input to your subflow input (the control number), and define an output variable called parsed_number of type String.

Step 3 — Set the flow variable

After the Script step, add a Set Flow Variables step (or do it inline if your version supports it):

  • Set parsed_control_number = Script Step → parsed_number

Step 4 — Update Look Up Record

In your Look Up Record action, change the filter condition from using the raw subflow input to using the flow variable instead:

  • Table: sn_compliance_control
  • Condition: number is fd_data.subflow_inputs.parsed_control_number

(Or pick it from the data pill picker under Flow Variables → parsed_control_number)

Step 5 — Test

Run the test again. The Script step will strip the JSON wrapper, and the Look Up Record will receive just CTRL0021175 as a clean string.

If after this it's still passing the JSON object, add a gs.info('RAW INPUT: ' + raw) line at the top of the script to log what's actually arriving — that'll confirm the exact format being sent and you can adjust the parsing accordingly.

View solution in original post

Its_Azar
Mega Sage

Thanks @Naveen20 

You were right, we needed to satinise the input, and then pass it to lookup, your script wasnt working, sharing the script which worked.

 

(function execute(inputs, outputs) {
// ... code ...

    var ctrl = inputs.control_number;

    if (typeof ctrl === 'object' && ctrl.input) {
        outputs.cleaned_control_number = ctrl.input;
    } else {
        outputs.cleaned_control_number = ctrl;
    }

})(inputs, outputs);
☑️ If this helped, please mark it as Helpful or Accept Solution so others can find the answer too.

Kind Regards,
Azar
Serivenow Rising Star
Developer @ KPMG.

View solution in original post

4 REPLIES 4

Naveen20
ServiceNow Employee

 

The root cause is the skill input datatype. In Image 3, the input is configured as Record (with table sn_compliance_control). When AI Agent Studio passes a Record-type input to the subflow tool, it wraps the value in a JSON object like {"input":"CTRL0013156"} instead of passing the plain string CTRL0013156. That's exactly what the error in Image 1 shows — the Look Up Record action is trying to query number={"input":"CTRL0013156"}, which naturally returns no results.

The fix: Change the skill input datatype from Record to String. Since the subflow only needs the control number as a plain text value to perform the lookup, there's no reason to use the Record datatype. The Record type is intended for passing an actual record reference (sys_id based), not a display value like a number field.

Steps:

  1. Open the skill input configuration.
  2. Change Datatype from Record to String.
  3. Remove the table name (it won't be needed for String type).
  4. Update the test record value to just the string CTRL0021175.
  5. Save and re-run the test.

This way the subflow will receive the raw string CTRL0013156 and the Look Up Record encoded query will correctly resolve to number=CTRL0013156.

If for some reason they need to keep the Record datatype (e.g., for grounding or context), the alternative is to add a Script step in the subflow before the Look Up Record action that parses the JSON input and extracts just the value — something like:

var rawInput = fd_data.subflow_inputs.control_number; // however the input is named
if (rawInput && rawInput.indexOf('{') === 0) {
    var parsed = JSON.parse(rawInput);
    rawInput = parsed.input || '';
}
// use rawInput in subsequent steps

But switching to String is the cleaner and recommended approach here.

Tried with type string but its the same, I have a input field for my flow, are u suggesting adding a flow var and then scripting that? if possible pls walk me through the script step, 

 

☑️ If this helped, please mark it as Helpful or Accept Solution so others can find the answer too.

Kind Regards,
Azar
Serivenow Rising Star
Developer @ KPMG.

Naveen20
ServiceNow Employee

Add a Script step in the subflow before the Look Up Record action, parse out the actual number, set it into a flow variable, and use that variable in the Look Up Record.

Here's the walkthrough:

Step 1 — Create a new flow variable

Open your subflow, go to the flow variables section, and create a new variable:

  • Name: parsed_control_number
  • Type: String

Step 2 — Add a Script step

Add a Script Step (Flow Logic → Script) as the very first action in your subflow, before the Look Up Record. Use this script:

(function execute(inputs, outputs) {

    var raw = inputs.control_number; // your subflow input variable name

    if (raw) {
        raw = raw.toString().trim();

        // If AI Agent Studio wrapped it in JSON, extract the value
        if (raw.indexOf('{') === 0) {
            try {
                var parsed = JSON.parse(raw);
                raw = parsed.input || parsed.number || '';
            } catch (e) {
                // Not valid JSON, use as-is
            }
        }

        // Strip any extra quotes that may remain
        raw = raw.replace(/^"|"$/g, '');
    }

    outputs.parsed_number = raw || '';

})(inputs, outputs);

In the Script step configuration, map the input to your subflow input (the control number), and define an output variable called parsed_number of type String.

Step 3 — Set the flow variable

After the Script step, add a Set Flow Variables step (or do it inline if your version supports it):

  • Set parsed_control_number = Script Step → parsed_number

Step 4 — Update Look Up Record

In your Look Up Record action, change the filter condition from using the raw subflow input to using the flow variable instead:

  • Table: sn_compliance_control
  • Condition: number is fd_data.subflow_inputs.parsed_control_number

(Or pick it from the data pill picker under Flow Variables → parsed_control_number)

Step 5 — Test

Run the test again. The Script step will strip the JSON wrapper, and the Look Up Record will receive just CTRL0021175 as a clean string.

If after this it's still passing the JSON object, add a gs.info('RAW INPUT: ' + raw) line at the top of the script to log what's actually arriving — that'll confirm the exact format being sent and you can adjust the parsing accordingly.

Its_Azar
Mega Sage

Thanks @Naveen20 

You were right, we needed to satinise the input, and then pass it to lookup, your script wasnt working, sharing the script which worked.

 

(function execute(inputs, outputs) {
// ... code ...

    var ctrl = inputs.control_number;

    if (typeof ctrl === 'object' && ctrl.input) {
        outputs.cleaned_control_number = ctrl.input;
    } else {
        outputs.cleaned_control_number = ctrl;
    }

})(inputs, outputs);
☑️ If this helped, please mark it as Helpful or Accept Solution so others can find the answer too.

Kind Regards,
Azar
Serivenow Rising Star
Developer @ KPMG.