Error messages, decoded
What does the SuiteQL error 'Invalid or unsupported search' mean?
Short answer
A generic refusal carrying no error code, no position and no identifier name. In this run it came from CAST(id AS VARCHAR(20)), a date column compared to a bare ISO string, GROUPING SETS, and one RIGHT JOIN.
It is a refusal, not a diagnosis. The string carries no error code, no character offset and no identifier name, so it does not tell you which part of the statement it objected to. Bisect the statement and swap the refused construct for one the engine accepts.
Minimal reproduction
SELECT CAST(id AS VARCHAR(20)) AS s FROM transaction FETCH FIRST 3 ROWS ONLY
N/query.runSuiteQL error: Search error occurred: Invalid or unsupported search
That is the whole error.
Which error family you are in
Three generic-looking strings come out of this engine and they are not interchangeable.
| String | What it looks like |
|---|---|
Search error occurred: Invalid or unsupported search |
The bare sentence above. No code, no position, no name. |
Unexpected Error |
Even barer. No code, no position, no name, and note it arrives with no Search error occurred: wrapper at all. |
Failed to parse SQL [...]: syntax error, state:0(10102) near: FETCH(1,44, token code:0) |
Echoes your statement and points at a token. |
The third one is the trap. An unresolvable column is the most common cause of syntax error ... near: FETCH(1,NN, token code:0), but it is not the only thing an unresolvable column can produce: the same shape, a column that does not exist on the table plus a FETCH FIRST clause, returned a bare Unexpected Error. So the rule to follow is the action, not the diagnosis: if SuiteQL blames your FETCH clause, delete the FETCH clause and run again, because the second error names the real problem.
The four constructs that produced it, and what the run tested in their place
| Refused | What the run tested in its place |
|---|---|
CAST(id AS VARCHAR(20)) |
No substitute. TO_CHAR on a date column, TO_NUMBER('42') and TO_DATE('2026-01-15','YYYY-MM-DD') all run, but none of them converts a number to a string, and TO_CHAR on a numeric column was not tested. |
WHERE trandate >= '2026-01-01', a bare ISO string |
TO_DATE('2026-01-01','YYYY-MM-DD'), DATE '2026-01-01' and '1/1/2026' in the account's own display format all run, and all three returned the identical count. |
GROUP BY GROUPING SETS ((type), (status)) |
GROUP BY ROLLUP(type) runs, and its null-marker superaggregate row is the true grand total. |
transaction t RIGHT JOIN transactionAccountingLine tal ON 1 = 0 |
No outer join to transactionAccountingLine succeeded. The only join to that table the run got working is the inner compound-key form, ON tl.transaction = tal.transaction AND tl.id = tal.transactionline. |
TO_CHAR with an explicit format mask does run, on a date column:
SELECT TO_CHAR(trandate, 'YYYY-MM-DD') AS d FROM transaction FETCH FIRST 3 ROWS ONLY
It returns the value as a string rendered exactly per the mask, with no time component. That is a date going in. The numeric case, which is what CAST(id AS VARCHAR(20)) was doing, was not tested at all, so test it in your own account before relying on it.
Why this happens
Four unrelated constructs return the identical string, which is what makes it a catch-all rather than a diagnosis. The distinction from the parse errors is directly observed: those name a state, a token and an offset, and this one is a bare sentence.
Beyond that it is inference. Nothing in the run establishes which execution stage raises it. For GROUPING SETS specifically, the attribution rests on ROLLUP succeeding in an otherwise similar statement, not on the error text, which names nothing.
Do not read the string as "the search is invalid". None of these four cases involved a saved search.
How to tell if you are affected
This error is loud, so the risk is not missing it. The risk is its neighbour that fails silently. The RIGHT JOIN above is refused outright when the right side is transactionAccountingLine, but the same join against transactionLine returns a plausible wrong number instead of an error. Run these two statements separately:
SELECT COUNT(*) AS n FROM transaction t RIGHT JOIN transactionLine tl ON 1 = 0
SELECT COUNT(*) AS n FROM transactionLine
ON 1 = 0 matches nothing, so a working RIGHT JOIN has to null-supply every line row and the first statement must return exactly the second statement's count. If instead the first returns zero, the join ran as an inner join, and every orphan hunt you have run against that pair has been answering "none found" for the wrong reason. Here the first returned zero. Full details are on the RIGHT JOIN page.
Scope: one production account on NetSuite 2026.1, entirely through N/query.runSuiteQL. This finding was not tested on the REST endpoint. The error strings above are NetSuite's text verbatim.
Not every statement named on this page is a failure. Four of them produced this error: the CAST to VARCHAR, the date column compared to a bare ISO string, the GROUPING SETS clause, and the RIGHT JOIN to transactionAccountingLine. The rest are controls that succeeded: TO_CHAR on a date column, TO_NUMBER, TO_DATE, the DATE literal, the display-format date string, ROLLUP, and the inner compound-key join to transactionAccountingLine. The unresolvable-column statements are mentioned only for the error-family comparison above. These four triggers are the ones seen in one run, not the full list.
How this was established
14 probe runs against one live NetSuite 2026.1 account on the Administrator role, through N/query.runSuiteQL. Where this page draws a boundary around a finding, that boundary is the edge of what was actually run.
Related
- SuiteQL says syntax error near FETCH, but my FETCH FIRST clause is fine. What is wrong?
Your FETCH clause is probably fine. A column that does not exist on the table is the usual cause. Delete the FETCH FIRST clause, run the statement again, and the second error names the real problem.
- What does 'N/query.runSuiteQL error: Unexpected Error' mean in SuiteQL?
It carries no code, no position and no identifier name. Read it as "something here is unsupported" and bisect the query. In this run it came from three BUILTIN calls and from a column that does not exist.
- How do I compare a date column to a date literal in SuiteQL?
TO_DATE('2026-01-01','YYYY-MM-DD'), DATE '2026-01-01' and the bare string '1/1/2026' all work and returned identical counts. The bare ISO string '2026-01-01' fails with "Invalid or unsupported search". BETWEEN with TO_DATE on both sides works.
- Why does my SuiteQL RIGHT JOIN between transaction and transactionLine return 0 rows?
RIGHT JOIN between transaction and transactionLine runs as an inner join and returns zero rows. FULL OUTER is downgraded to a LEFT join from the header. No error. LEFT JOIN from the header and Oracle (+) both work.