Singular expression refers to non-unique object.

Hi All, I’m relatively new to BIgfix Relevance. I would be most grateful if anyone could help point out why I get the Singular expression refers to non-unique object. when I run the below in Fixlet Debugger.

Even though it outputs the result I want, it still shows Singular expression refers to non-unique object. as shown below.

Q: if exists lines of files whose((it starts with "esp_processing_data" AND it contains ".xml") of (name of it as lowercase)) of folder "C:\postilion\eSocket.POS\incoming" then preceding text of first  " " of substring after "=%22" of line 418 of file whose((it starts with "esp_processing_data" AND it contains ".xml") of (name of it as lowercase)) of folder "C:\postilion\eSocket.POS\incoming" & (" - BigFix Checked it on " & (preceding text of last " " of (following text of first " " of (now as  string)))) else "MID Unknown"
A: 7102924 - BigFix Checked it on 17 May 2020 12:50:50
E: Singular expression refers to non-unique object.

Many thanks.

K

1 Like

This is a really great question, and one in which everyone writing relevance will eventually hit.

BigFix Relevance has 2 forms, Singular and Plural.

Singular Relevance MUST have exactly 1 result. 0 results is an error, 2 or more results is an error.

Plural Relevance is “valid” no matter how many results it has, no hard errors should generally be thrown by plural relevance, with some exceptions. This means there can be 0 results, or 1 result, or 2+ results, and all options are equally fine as far as the “validity” of the relevance is concerned.

So in your case, the error Singular expression refers to non-unique object. means that your relevance is written such that there must be exactly 1 result, but there is in-fact NOT exactly 1 result. In this particular case, since it is showing 1 result before throwing this error, then that means there are 2 or more results.

This is why I recommend that ALL relevance is written to be plural. BUT if you follow this advice, then you will eventually run into the opposite problem, the error: A singular expression is required.

See this example:

16 PM

If we wanted to know if there was at least 1 result which was 0 we can’t directly compare 2 different numbers to a single number, because this doesn’t make sense, we would instead do this:

30 PM

In this case, we are filtering all results down to only those which are 0, then doing the comparison.

The longer version is basically, always write plural relevance, unless it is within a clause surrounded by parenthesis like … whose( ) or ( ) of … Example: Plural to Singular? Formatting options? Unique? Help? - #5 by jgstew

So the real question is, how do we rewrite your relevance, such that it can always be plural?

  1. Reorder the flow of relevance to be Right to Left as much as possible
  2. Pluralize all of the relevance
  3. IF/THEN/ELSE actually becomes unnecessary and is inefficient, so remove that

This should be the final result:

(it as trimmed string & " - BigFix Checked it on " & preceding text of last " " of following text of first " " of (now as string) ) of preceding texts of firsts " " of substrings after "=%22" of lines 418 of files whose((it starts with "esp_processing_data" AND it contains ".xml") of (name of it as lowercase)) of folders "C:\postilion\eSocket.POS\incoming"

This relevance should be faster to execute, plus handle multiple results, instead of just a singular result. ALSO in the case in which there are 0 results, it will report <none> instead of throwing an error, but it also won’t return the helpful message MID Unknown. It is actually most efficient to just report <none>, but if you REALLY want to return MID Unknown then it is possible to add that back in a few different ways, but I won’t go into that right this second unless it is a “must”.

Related:

2 Likes

jgstew,

You’re awesome!

Many thanks, for your guidance and solution to my query. Your resultant relevance has worked a charm.

I will adopt your 3 stepped approach moving forward.

I’m most grateful :smiley:

1 Like

Reviving this question. I am having the same issue and I am not able to figure out how to convert my relevance to fix it as described above.

 ("Version " & following text of first "=" of line containing "ScriptVer=" of file  (((path of it) of network share whose (name of it as string as lowercase = "netlogon" as string as lowercase)) & "\Agent\install.bat")) | "Not Detected"

q: ("Version " & following text of first "=" of line containing "ScriptVer=" of file  (((path of it) of network share whose (name of it as string as lowercase = "netlogon" as string as lowercase)) & "\Agent\install.bat")) | "Not Detected"
A: Version 13
E: Singular expression refers to non-unique object.

Any help would be appreciated.

Is there any possibility of more than one file named "\Agent\install.bat" on the netlogon share? Is there more than one line in the file that contains the string "ScriptVer="?

You have to have singular strings in order to use the & to join them together.

Also, note that the network share object may not return a value when evaluated by the agent, since it runs in the LocalSystem security context.

There are exactly two lines in the batch file that contain “ScriptVer=”

The first one sets the value to the current version and at the end of the file, it is used to unset the variable.

I used to only have it in the file once but started clearing it because it was not in the local. I could remove the second one but I won’t be able to do it until I update to version 14.

It works with other analysis we have.

I was using “\127.0.0.1\netlogon\Agent\install.bat” but @JasonWalker advised not to use the share like that, it may not be reachable.

There are several ways to handle this, but I think the most straightforward is to filter the ‘lines’ so only one line is returned.

My test sample:

q: lines of file "c:\temp\test.bat"
A: set ScriptVer=13
A: echo Did some things
A: set ScriptVer=
T: 1.477 ms
I: plural file line

// Filter the line selection so only one line is returned; otherwise the singular comparisons and concatenations fail to to ‘singular expression’ errors

q: ("Version " & following text of first "=" of line containing "ScriptVer=" whose (it as trimmed string does not end with "=") of file "c:\temp\test.bat") | "Not Detected"
A: Version 13
T: 0.852 ms
I: singular string

In general one could also change the expression to ("header" & it) of (some plural expression) to concatenate with plural results. That would yield


q: ("Version "  & it) of following texts of firsts "=" of lines containing "ScriptVer=" of file "c:\temp\test.bat"
A: Version 13
A: Version 
T: 0.337 ms
I: plural string

But that also breaks the error-checking you’re doing with the pipe operator, which is doing important things in this context, so I like the first solution for this case better.

1 Like

(as a total side-note, if you have this issue where you have unwanted environment variables persisting after you run your batch, you could use SETLOCAL at the start and ENDLOCAL at the end of the script so all of the variables you defined are discarded)

The ENDLOCAL does discard all other variables but the SetVer is before the local starts, on purpose. I guess I could put another end local at the end, that may take care of it. But I would have to wait until the next version. I think your first solution is best. I should have thought of that. I am usually the one thinking outside the box. :slight_smile:

1 Like