Saved Search Answers

Filters and criteria

Why equalto is not valid on internalid in NetSuite searches

Updated
  • saved-search
  • internalid
  • operators
  • criteria
  • error-message
  • anyof

Why is equalto not a valid operator on internalid in a saved search filter (SSS_INVALID_SRCH_OPERATOR)?

Because NetSuite does not accept equalto on internalid: the filter is refused with SSS_INVALID_SRCH_OPERATOR and the search returns an error instead of rows. Use anyof, which takes an array and scales to a list. is also works, on a bare string, which is the part most people do not expect.

Because NetSuite does not accept equalto on internalid. The filter object itself is refused and the search returns an error instead of rows. Use anyof.

The rejection, verbatim:

SSS_INVALID_SRCH_OPERATOR
An nlobjSearchFilter contains an invalid operator, or is not in proper syntax: internalid.

Note that the message names the field, not the operator. It tells you where the problem is and not what it is, which is why people go looking for a broken join or a permissions issue on a filter that is one word away from working. That text is also the whole of what the engine says about it: this run measured which spellings are accepted, not NetSuite's reason for refusing this one.

Minimal reproduction

Four filters on the same transaction search, one internal id, one call each:

internalid anyof ['2']       -> rows
internalid is    '2'         -> the same rows
internalid equalto '2'       -> SSS_INVALID_SRCH_OPERATOR
internalid noneof ['2']      -> every other row, exactly

Of the three natural spellings of "this id and no other", two work and the SQL-looking one does not. That is the whole finding. equalto is the operator most people reach for by analogy with SQL, and it is the one that fails.

Use anyof

anyof takes an array, so it is the form that scales from one id to a list without a rewrite:

internalid anyof ['2']
internalid anyof ['2','3']

Adding the second id returned the lines of both transactions and nothing else. Nothing about the filter changes shape as the list grows, which is the practical argument for making anyof your default even when you only have one value in hand today.

is also works, and that is worth stating plainly because it contradicts a reasonable expectation. internalid behaves like a select-type field, and you would expect such a field to want an array rather than a bare string. Here the bare string is accepted, and it returned the same rows as anyof did for the same single id. So is is not wrong, it just does not scale.

noneof is the clean complement. Measured against the whole search with a summary column, the row count it returned was the search's own total minus the lines of the excluded transaction, to the row. No off-by-one, nothing dropped. If you want everything except a handful of ids, noneof behaves the way you would hope.

Counting the rows of a transaction search takes a little care, because one transaction is several lines and a summary Count does not return what you expect. That is a separate page.

How to tell if you are affected

This one is loud, which makes the audit easy. Grep your SuiteScripts and your integration code for equalto in the same expression as internalid, or for a search filter list assembled from a config where the operator is a string somebody typed. Any of them that ran would have thrown SSS_INVALID_SRCH_OPERATOR at the point of execution, so if a script is running in production it is not doing this.

The failure to actually worry about is the silent cousin. Swap the field for a text formula and every operator becomes a string operator, so contains on an internal id turns into a substring scan over the digits, returns a plausible number of rows and raises nothing at all. That mistake reaches production, where this one cannot. It has its own page.

Scope

One sandbox account on NetSuite 2026.1, Administrator role, transaction search, one internal id and one pair of ids. These searches were built and run ad hoc through the SuiteScript search engine (nlapiCreateSearch / runSearch) without saving anything, so the error above is the search engine's, raised on the filter object. The run did not enumerate the operator dropdown that the saved search form offers for Internal ID in the browser, so this page does not claim what that dropdown lists.

How this was established

1 probe run against one NetSuite 2026.1 sandbox account on the Administrator role, through the saved search UI and the SuiteScript search engine. Where this page draws a boundary around a finding, that boundary is the edge of what was actually run.

Related