Download

An expression of non-boolean type specified in a context where a condition is expected

T-SQL has no true/false values you can use on their own, so WHERE, ON, HAVING, IF, WHILE and CASE WHEN need a comparison: active = 1, not active; email IS NOT NULL, not email; 1 = 1, not TRUE. The “near” part points right after the incomplete condition.

SQL Server error 4145· Tested on SQL Server 2022 RTM-CU27 (16.0.4295.3); same messages on 2019 RTM-CU32-GDR and 2025 RTM-CU9· Updated 11 October 2026

An expression of non-boolean type specified in a context where a condition is expected, near ';'.

What it means

In T-SQL, a condition has to be a predicate: a comparison (=, <>, <…), IN, LIKE, BETWEEN, EXISTS or IS [NOT] NULL, joined with AND, OR and NOT. A column, a variable, a number or a function call on its own isn’t one, even when it holds 1 or 0. WHERE, ON, HAVING, IF, WHILE, CASE WHEN and the first argument of IIF all need a condition, so SQL Server rejects the batch and runs none of it:

Msg 4145, Level 15, State 1, Server 7732422b7f56, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near ';'.

The near part is where SQL Server expected the rest of the condition; often that’s the ;, THEN, PRINT or closing bracket right after it.

Common causes

  1. A bit column or variable used as a flag: WHERE active, WHERE @include_archived. bit is a number (0, 1 or NULL), not a true/false value.
  2. Habits from other databases: WHERE TRUE, WHERE email (meaning “has an email”), PostgreSQL’s ILIKE (4145 near 'ILIKE').
  3. Half a condition: WHERE name = N'Ada' OR N'Lin', or ON o.customer_id with nothing to compare it with.
  4. IF on a count: IF (SELECT COUNT(*) FROM …) PRINT ….
  5. A row-value comparison: WHERE (id, name) IN (SELECT …), which T-SQL doesn’t support (4145 near ',').
  6. A function that returns bit used directly: WHERE dbo.is_active(id).

How to fix it

Compare explicitly

Instead ofWrite
WHERE activeWHERE active = 1
WHERE @include_archivedWHERE @include_archived = 1
WHERE emailWHERE email IS NOT NULL (and AND email <> '' if empty strings count as missing)
WHERE TRUEWHERE 1 = 1
WHERE name = N'Ada' OR N'Lin'WHERE name IN (N'Ada', N'Lin')
ON o.customer_idON o.customer_id = c.id
CASE WHEN email THEN …CASE WHEN email IS NOT NULL THEN …
IIF(active, 'yes', 'no')IIF(active = 1, 'yes', 'no')
WHERE dbo.is_active(id)WHERE dbo.is_active(id) = 1

Use EXISTS for “are there any rows”

IF EXISTS (SELECT 1 FROM dbo.orders WHERE status = 'new')
  PRINT 'new orders waiting';

EXISTS stops at the first row; (SELECT COUNT(*) …) > 0 also works but counts them all.

Replace row-value IN with EXISTS

SELECT c.id
FROM dbo.customers AS c
WHERE EXISTS (SELECT 1 FROM dbo.orders AS o
              WHERE o.customer_id = c.id AND o.status = 'paid');

ILIKE: use LIKE

Under the usual case-insensitive collations (SQL_Latin1_General_CP1_CI_AS, the default on our test servers), LIKE already ignores case. On a case-sensitive column, compare LOWER(name) LIKE N'a%', or add COLLATE with a _CI_ collation.

Reproduce it

On SQL Server 2022 (16.0.4295.3) with sqlcmd, each statement in its own batch:

SELECT id FROM seo_err_mssql.customers WHERE email;
SELECT id FROM seo_err_mssql.customers WHERE name ILIKE N'a%';
SELECT CASE WHEN email THEN 'has email' ELSE 'none' END FROM seo_err_mssql.customers;
IF (SELECT COUNT(*) FROM seo_err_mssql.customers) PRINT 'rows';
SELECT id FROM seo_err_mssql.customers WHERE (id, name) IN (SELECT customer_id, status FROM seo_err_mssql.orders);
Msg 4145, Level 15, State 1, Server 7732422b7f56, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near ';'.
Msg 4145, Level 15, State 1, Server 7732422b7f56, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near 'ILIKE'.
Msg 4145, Level 15, State 1, Server 7732422b7f56, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near 'THEN'.
Msg 4145, Level 15, State 1, Server 7732422b7f56, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near 'PRINT'.
Msg 4145, Level 15, State 1, Server 7732422b7f56, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near ','.

WHERE TRUE, WHERE @active (a bit variable set to 1), ON o.customer_id, WHERE name = N'Ada' OR N'Lin', HAVING COUNT(*) and WHERE dbo.order_count(id) all failed near ';', and IIF(email, 1, 0) near '('. Rewritten as @active = 1 AND email IS NOT NULL AND name IN (N'Ada', N'Lin') AND name LIKE N'a%', the query returned Ada, so LIKE ignored case on this collation; WHERE 1 = 1 returned all three customers. SQL Server 2019 and SQL Server 2025 printed the same messages: none of them accepts TRUE or a bare bit as a condition.

In Inlet

When SQL Server rejects the batch, Inlet shows its message with SQL Server error 4145, state 1, severity 15 and links to this page. With your own Anthropic API key, Ask Claude (Pro, ⌘L) can fix a failed statement, and writes T-SQL when you’re translating a query from PostgreSQL or MySQL; it sends the schema and the SQL, never rows.

Inlet: a database client for the Mac

One native app for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and Redis. It explains errors where they happen, holds your edits until you save them, and keeps production read-only until you say so.

Version 0.1.0 · macOS 26 Tahoe or later · Apple silicon and Intel