- Error number
- 4145
- Severity
- 15 (user-correctable error)
- State
- 1
- Product
- Microsoft SQL Server Database Engine
- Versions
- All supported SQL Server versions (2016 to 2025), Azure SQL Database, Azure SQL Managed Instance
- Category
- Syntax & Object Resolution
- Last reviewed
- 24 October 2026
On this page
What it means
Error 4145 means WHERE, IF, WHILE, CASE WHEN, HAVING or ON was given a plain value such as a bit column instead of a true or false comparison, so the condition is incomplete.
T-SQL has no boolean data type that you can store or select. A condition must be a predicate: a comparison (=, >, <>), IS NULL, LIKE, IN, EXISTS or BETWEEN, combined with AND, OR and NOT. A bit column or variable is a number (0 or 1), not a predicate, so WHERE is_active is rejected by the parser with 4145 at severity 15 and the batch does not run.
The token after near is not the mistake itself but the first thing the parser met after the incomplete condition: ORDER, THEN, PRINT, BEGIN or the closing semicolon. Look immediately to the left of it. The habit usually comes from C#, JavaScript, Python or MySQL, where a number or a flag can be used as a condition directly.
Common causes
- A bit column used on its own:
WHERE is_activeorWHERE NOT is_deleted. - A flag variable used directly in
IF @debugorWHILE @keep_going. CASE WHEN is_active THEN ...without a comparison.- A number or function result used as a condition, such as
HAVING COUNT(*),WHERE stockorAND LEN(@s). - A join with
ON p.idwhere the= other.idpart was lost while editing.
Diagnose it
Read-only These queries only read metadata and dynamic management views. They do not change data, permissions or configuration, so they are safe to run first.
Check the column type behind the condition
SELECT c.name AS column_name, TYPE_NAME(c.user_type_id) AS data_type
FROM sys.columns AS c
WHERE c.object_id = OBJECT_ID(N'dbo.Products')
ORDER BY c.column_id; A bit column needs = 1 or = 0; an int column needs a comparison such as > 0, and text needs <> '' or IS NOT NULL, depending on what you mean.
Check the corrected query compiles
EXEC sp_describe_first_result_set
N'SELECT name FROM dbo.Products WHERE is_active = 1 ORDER BY name;'; One row for the name column. The same call reports 4145 while a condition is still incomplete.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Compare flags with = 1 or = 0
Read-onlyWrite out the comparison. For a nullable bit column, decide how NULL should behave: = 0 does not match NULL rows.
SELECT name
FROM dbo.Products
WHERE is_active = 1
ORDER BY name;
Use explicit comparisons in IF, WHILE and CASE
Read-onlyThe same rule applies to procedural code and CASE expressions.
DECLARE @debug bit = 1;
IF @debug = 1
PRINT 'Debug mode';
SELECT name, CASE WHEN is_active = 1 THEN 'yes' ELSE 'no' END AS active
FROM dbo.Products;
Say what a number or text value should satisfy
Read-onlyFor numbers, decide between > 0 and <> 0; for HAVING, compare the aggregate; for text, test for NULL or emptiness explicitly.
SELECT is_active, COUNT(*) AS products
FROM dbo.Products
WHERE stock > 0
GROUP BY is_active
HAVING COUNT(*) > 1;
Examples
A bit column used as the whole WHERE condition
CREATE TABLE dbo.Products (id INT PRIMARY KEY, name NVARCHAR(50), is_active BIT, stock INT);
SELECT name
FROM dbo.Products
WHERE is_active -- no comparison
ORDER BY name;
Msg 4145, Level 15, State 1, Line 6 An expression of non-boolean type specified in a context where a condition is expected, near 'ORDER'.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
IF on a bit variable
DECLARE @debug bit = 1;
IF @debug
PRINT 'Debug mode';
Msg 4145, Level 15, State 1, Line 3 An expression of non-boolean type specified in a context where a condition is expected, near 'PRINT'.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
CASE WHEN without a comparison
CREATE TABLE dbo.Products (id INT PRIMARY KEY, name NVARCHAR(50), is_active BIT, stock INT);
SELECT name,
CASE WHEN is_active THEN 'yes' ELSE 'no' END AS active
FROM dbo.Products;
Msg 4145, Level 15, State 1, Line 4 An expression of non-boolean type specified in a context where a condition is expected, near 'THEN'.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
How to prevent it
Treat every condition as a question with an explicit comparison, even for flags. It reads clearly, ports between database engines, and forces a decision about NULL rows. Compile new queries with sp_describe_first_result_set or a quick run against an empty test table before they reach a deployment script.
For how WHERE conditions are built from comparisons, see the SQL WHERE clause explained and the CASE expression reference.
Common questions
Does SQL Server have a boolean type?
Not one you can store or select. bit holds 0, 1 or NULL and behaves like a number. Conditions produce true, false or unknown internally, but you must write them as comparisons or predicates.
Why does the message point at ORDER or THEN when the mistake is earlier?
The parser only notices the condition is incomplete when it reaches the next keyword. The real problem is the expression just before the quoted token.
WHERE is_active works in MySQL. Why not in SQL Server?
MySQL treats any non-zero number as true in a condition. SQL Server requires a predicate, so write WHERE is_active = 1.
Learn more on CodeWithSQL
Official documentation
- Search condition (Transact-SQL)
- IF...ELSE (Transact-SQL)
- bit (Transact-SQL)
- Database Engine events and errors 4000 to 4999
Last technically reviewed 24 October 2026; examples and diagnostics run on SQL Server 2025 (17.0.1145.4). Message text checked against the engine's sys.messages catalogue.