---
title: "ESLint Plugin Drizzle"
description: "The eslint-plugin-drizzle package provides static analysis rules for Drizzle ORM to prevent destructive, accidental database modifications during development. It exposes rule modules for enforcing ..."
last_updated: "2026-10-12T08:14:00.811777+00:00"
canonical_url: "https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/ecosystem-packages/eslint-plugin-drizzle"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [eslint-plugin-drizzle/src/enforce-update-with-where.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts)
- [eslint-plugin-drizzle/src/enforce-delete-with-where.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts)
- [drizzle-kit/src/sqlgenerator.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/sqlgenerator.ts)
- [eslint-plugin-drizzle/src/configs/all.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/all.ts)
- [drizzle-orm/src/gel-core/dialect.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel-core/dialect.ts)
- [eslint-plugin-drizzle/src/configs/recommended.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/recommended.ts)
- [drizzle-kit/src/cli/commands/pgPushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/pgPushUtils.ts)
- [eslint-plugin-drizzle/src/index.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/index.ts)
- [drizzle-orm/src/mysql-core/dialect.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/mysql-core/dialect.ts)
- [drizzle-kit/src/serializer/gelSerializer.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/gelSerializer.ts)
- [eslint-plugin-drizzle/src/utils/options.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts)
- [drizzle-kit/src/cli/commands/singlestorePushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/singlestorePushUtils.ts)
- [.eslintrc.yaml](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/.eslintrc.yaml)
- [eslint-plugin-drizzle/src/utils/ast.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/ast.ts)
- [drizzle-orm/src/singlestore-core/dialect.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/singlestore-core/dialect.ts)
- [drizzle-orm/type-tests/mysql/select.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/mysql/select.ts)
- [drizzle-orm/type-tests/pg/select.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/pg/select.ts)
- [drizzle-orm/type-tests/mysql/delete.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/mysql/delete.ts)
- [drizzle-orm/type-tests/geldb/select.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/geldb/select.ts)
- [drizzle-orm/type-tests/pg/no-strict-null-checks/test.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/pg/no-strict-null-checks/test.ts)
- [drizzle-orm/type-tests/mysql/update.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/mysql/update.ts)
- [drizzle-orm/type-tests/geldb/no-strict-null-checks/test.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/geldb/no-strict-null-checks/test.ts)
- [drizzle-orm/type-tests/mysql/no-strict-null-checks/test.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/mysql/no-strict-null-checks/test.ts)
- [drizzle-orm/type-tests/sqlite/delete.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/sqlite/delete.ts)
- [drizzle-kit/src/cli/commands/mysqlPushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/mysqlPushUtils.ts)
- [drizzle-orm/type-tests/pg/with.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/pg/with.ts)
- [drizzle-orm/type-tests/singlestore/delete.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/singlestore/delete.ts)
- [drizzle-orm/type-tests/sqlite/no-strict-null-checks/test.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/type-tests/sqlite/no-strict-null-checks/test.ts)
</details>

## Overview

The `eslint-plugin-drizzle` package provides static analysis rules for Drizzle ORM to prevent destructive, accidental database modifications during development. It exposes rule modules for enforcing conditional `where` clauses on both deletion and update operations, protecting against accidental whole-table wipes.
Sources: [eslint-plugin-drizzle/src/index.ts:9-12](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/index.ts#L9-L12), [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:16-17](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L16-L17), [eslint-plugin-drizzle/src/enforce-update-with-where.ts:15-17](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L15-L17)

The plugin bundles ready-to-use configuration presets, including `recommended` and `all`, which register rules such as `drizzle/enforce-delete-with-where` and `drizzle/enforce-update-with-where` as compilation errors.
Sources: [eslint-plugin-drizzle/src/configs/recommended.ts:10-13](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/recommended.ts#L10-L13), [eslint-plugin-drizzle/src/configs/all.ts:10-13](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/all.ts#L10-L13), [eslint-plugin-drizzle/src/index.ts:14](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/index.ts#L14)

By traversing abstract syntax tree (AST) member expressions and call chains via custom AST resolution utilities, the plugin matches configured database client identifiers and flags query builders missing explicit filter conditions.
Sources: [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:36-47](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L36-L47), [eslint-plugin-drizzle/src/enforce-update-with-where.ts:35-54](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L35-L54), [eslint-plugin-drizzle/src/utils/ast.ts:3-35](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/ast.ts#L3-L35), [eslint-plugin-drizzle/src/utils/options.ts:23-41](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L23-L41)

## Plugin Architecture and Rule Exports

### Rule and Configuration Registrations

The `eslint-plugin-drizzle` entry point exports rules, configuration presets, and package metadata directly from its main module definition. The `rules` export object registers two specific static analysis rules (`enforce-delete-with-where` and `enforce-update-with-where`), typed against `TSESLint.RuleModule<string, Options>` using TypeScript's `satisfies` operator. Package version and name details are dynamically imported from `package.json` into the `meta` export property.

```typescript
import type { TSESLint } from '@typescript-eslint/utils';
import { name, version } from '../package.json';
import all from './configs/all';
import recommended from './configs/recommended';
import deleteRule from './enforce-delete-with-where';
import updateRule from './enforce-update-with-where';
import type { Options } from './utils/options';

export const rules = {
	'enforce-delete-with-where': deleteRule,
	'enforce-update-with-where': updateRule,
} satisfies Record<string, TSESLint.RuleModule<string, Options>>;

export const configs = { all, recommended };

export const meta = { name, version };
```
Sources: [eslint-plugin-drizzle/src/index.ts:1-16](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/index.ts#L1-L16)

| Export Name | Target Property / Source Module | Type / Definition |
| :--- | :--- | :--- |
| `rules` | `'enforce-delete-with-where'`, `'enforce-update-with-where'` | `Record<string, TSESLint.RuleModule<string, Options>>` |
| `configs` | `all`, `recommended` | Presets object containing rulesets |
| `meta` | `name`, `version` | Imported from `../package.json` |

Sources: [eslint-plugin-drizzle/src/index.ts:9-16](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/index.ts#L9-L16)

> [!NOTE]
> The `rules` record satisfies `TSESLint.RuleModule<string, Options>`, binding rule implementations to custom option types defined in `./utils/options`.
> Sources: [eslint-plugin-drizzle/src/index.ts:7-12](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/index.ts#L7-L12)

## Bundled Configuration Presets

### Preset Ruleset Configurations

The plugin defines two prepackaged configuration files, `recommended.ts` and `all.ts`, which share identical environment and rule settings to enforce query safety constraints. Both configuration exports configure the parser and environment settings for modern JavaScript and TypeScript projects while registering the core safety rules as errors.

```typescript
export default {
	env: {
		es2024: true,
	},
	parserOptions: {
		ecmaVersion: 'latest',
		sourceType: 'module',
	},
	plugins: ['drizzle'],
	rules: {
		'drizzle/enforce-delete-with-where': 'error',
		'drizzle/enforce-update-with-where': 'error',
	},
};
```
Sources: [eslint-plugin-drizzle/src/configs/recommended.ts:1-14](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/recommended.ts#L1-L14)

| Configuration Property | Value / Setting | Purpose |
| :--- | :--- | :--- |
| `env.es2024` | `true` | Enables ES2024 global variables and syntax parsing |
| `parserOptions.ecmaVersion` | `'latest'` | Sets the ECMAScript version to the latest standard |
| `parserOptions.sourceType` | `'module'` | Treats files as ECMAScript modules |
| `plugins` | `['drizzle']` | Registers the `drizzle` plugin namespace |
| `rules['drizzle/enforce-delete-with-where']` | `'error'` | Flags table deletions lacking a `where` filter |
| `rules['drizzle/enforce-update-with-where']` | `'error'` | Flags table updates lacking a `where` filter |

Sources: [eslint-plugin-drizzle/src/configs/recommended.ts:1-14](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/recommended.ts#L1-L14), [eslint-plugin-drizzle/src/configs/all.ts:1-14](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/all.ts#L1-L14)

> [!NOTE]
> The `all.ts` preset mirrors `recommended.ts` completely, establishing identical strict error reporting for both configuration exports across the codebase.
> Sources: [eslint-plugin-drizzle/src/configs/all.ts:1-14](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/configs/all.ts#L1-L14)

## Enforcing WHERE Clauses on Deletions

### Static Analysis and Rule Metadata

The `enforce-delete-with-where` rule uses `@typescript-eslint/utils` to inspect Abstract Syntax Trees (AST) and prevent accidental execution of unconstrained table deletions [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:1-18](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L1-L18). Defined via `ESLintUtils.RuleCreator`, the rule classifies failures under the `problem` meta type, marks itself as fixable via code, and accepts an options schema restricting configuration to the `drizzleObjectName` property [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:5-33](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L5-L33).

```typescript
const deleteRule = createRule<Options, MessageIds>({
	defaultOptions: [{ drizzleObjectName: [] }],
	name: 'enforce-delete-with-where',
	meta: {
		type: 'problem',
		docs: {
			description: 'Enforce that `delete` method is used with `where` to avoid deleting all the rows in a table.',
		},
		fixable: 'code',
		messages: {
			enforceDeleteWithWhere:
				"Without `.where(...)` you will delete all the rows in a table. If you didn't want to do it, please use `{{ drizzleObjName }}.delete(...).where(...)` instead. Otherwise you can ignore this rule here",
		},
		schema: [{
			type: 'object',
			properties: {
				drizzleObjectName: {
					type: ['string', 'array'],
				},
			},
			additionalProperties: false,
		}],
	},
```
Sources: [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:11-33](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L11-L33)

| Rule Metadata Property | Value / Setting | Description |
| :--- | :--- | :--- |
| `name` | `'enforce-delete-with-where'` | Registered rule identifier |
| `meta.type` | `'problem'` | Categorizes the rule as detecting potential code errors |
| `meta.fixable` | `'code'` | Indicates automatic fix capabilities exist |
| `meta.messages.enforceDeleteWithWhere` | `"Without \`.where(...)\` you will delete all the rows..."` | Warning message reported when `where` is omitted |
| `meta.schema` | Array containing option definitions | Validates `drizzleObjectName` as string or array |

Sources: [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:11-33](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L11-L33)

> [!WARNING]
> Omitting `.where(...)` on a Drizzle delete builder generates an AST match that triggers an error report, preventing accidental truncation of entire database tables [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:16-23](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L16-L23).
> Sources: [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:16-23](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L16-L23)

### Member Expression Traversal and State Tracking

The rule traversal visitor evaluates `MemberExpression` nodes to verify whether a `.delete` call is immediately preceded by a `.where` method [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:34-50](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L34-L50). It maintains a module-scoped `lastNodeName` variable to track the previously visited property identifier in chained method calls [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:9](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L9), [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:47](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L47). When `node.property.name` equals `'delete'`, `lastNodeName` is checked to ensure it is not `'where'`, and `isDrizzleObj(node, options)` validates that the expression originates from a registered database instance [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:37-38](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L37-L38).

```typescript
create(context, options) {
	return {
		MemberExpression: (node) => {
			if (node.property.type === 'Identifier') {
				if (node.property.name === 'delete' && lastNodeName !== 'where' && isDrizzleObj(node, options)) {
					context.report({
						node,
						messageId: 'enforceDeleteWithWhere',
						data: {
							drizzleObjName: resolveMemberExpressionPath(node),
						},
					});
				}
				lastNodeName = node.property.name;
			}
			return;
		},
	};
},
```
Sources: [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:34-52](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L34-L52)

> [!NOTE]
> The module-scoped `lastNodeName` tracker relies on sequential AST visitor traversal order; if `lastNodeName` equals `'where'`, the preceding `.delete()` call is considered safe [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:9](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L9), [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:38](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L38).
> Sources: [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:9](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L9), [eslint-plugin-drizzle/src/enforce-delete-with-where.ts:38](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-delete-with-where.ts#L38)

## Enforcing WHERE Clauses on Updates

### Rule Metadata and Configuration Schema

The `enforce-update-with-where` rule checks that database update statements include a `.where(...)` filter, preventing accidental modification of all rows in a table. It is registered via `@typescript-eslint/utils` under the name `'enforce-update-with-where'` with metadata type `'problem'` and fixable status `'code'` [eslint-plugin-drizzle/src/enforce-update-with-where.ts:1-18](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L1-L18).

```typescript
defaultOptions: [{ drizzleObjectName: [] }],
name: 'enforce-update-with-where',
meta: {
	type: 'problem',
	docs: {
		description: 'Enforce that `update` method is used with `where` to avoid deleting all the rows in a table.',
	},
	fixable: 'code',
	messages: {
		enforceUpdateWithWhere:
			"Without `.where(...)` you will update all the rows in a table. If you didn't want to do it, please use `{{ drizzleObjName }}.update(...).set(...).where(...)` instead. Otherwise you can ignore this rule here",
	},
	schema: [{
		type: 'object',
		properties: {
			drizzleObjectName: {
				type: ['string', 'array'],
			},
		},
		additionalProperties: false,
	}],
},
```
Sources: [eslint-plugin-drizzle/src/enforce-update-with-where.ts:11-32](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L11-L32)

| Rule Metadata Property | Value / Setting | Description |
| :--- | :--- | :--- |
| `name` | `'enforce-update-with-where'` | Registered rule identifier for update clause enforcement |
| `meta.type` | `'problem'` | Categorizes the rule as detecting potential logic errors |
| `meta.fixable` | `'code'` | Indicates code correction capabilities |
| `meta.messages.enforceUpdateWithWhere` | `"Without \`.where(...)\` you will update all the rows..."` | Warning message reported when `where` is omitted from `update().set()` |
| `meta.schema` | Array with `drizzleObjectName` property | Validates configuration options as a string or array, disallowing additional properties |

Sources: [eslint-plugin-drizzle/src/enforce-update-with-where.ts:11-32](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L11-L32)

> [!WARNING]
> Omitting `.where(...)` when modifying records via `update(...).set(...)` triggers an AST violation warning, protecting entire database tables from unfiltered bulk updates [eslint-plugin-drizzle/src/enforce-update-with-where.ts:16-21](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L16-L21).
> Sources: [eslint-plugin-drizzle/src/enforce-update-with-where.ts:16-21](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L16-L21)

### Member Expression Traversal and State Tracking

The rule listener inspects `MemberExpression` nodes to verify that `.set()` calls on an `update()` builder are preceded by `.where()` [eslint-plugin-drizzle/src/enforce-update-with-where.ts:33-45](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L33-L45). It utilizes a module-scoped variable `lastNodeName` to remember the previous property identifier across visitor executions [eslint-plugin-drizzle/src/enforce-update-with-where.ts:8](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L8), [eslint-plugin-drizzle/src/enforce-update-with-where.ts:54](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L54). When the current property is `'set'`, `lastNodeName` is verified not to be `'where'`, and `node.object` must be a `CallExpression` whose callee is an `update` member expression originating from a recognized Drizzle object [eslint-plugin-drizzle/src/enforce-update-with-where.ts:37-45](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L37-L45).

```typescript
create(context, options) {
	return {
		MemberExpression: (node) => {
			if (node.property.type === 'Identifier') {
				if (
					lastNodeName !== 'where'
					&& node.property.name === 'set'
					&& node.object.type === 'CallExpression'
					&& node.object.callee.type === 'MemberExpression'
					&& node.object.callee.property.type === 'Identifier'
					&& node.object.callee.property.name === 'update'
					&& isDrizzleObj(node.object.callee, options)
				) {
					context.report({
						node,
						messageId: 'enforceUpdateWithWhere',
						data: {
							drizzleObjName: resolveMemberExpressionPath(node.object.callee),
						},
					});
				}
				lastNodeName = node.property.name;
			}
			return;
		},
	};
},
```
Sources: [eslint-plugin-drizzle/src/enforce-update-with-where.ts:33-59](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L33-L59)

> [!NOTE]
> Unlike `enforce-delete-with-where` which targets the `.delete` call directly, `enforce-update-with-where` targets the `.set` method node when verifying that `.where` was not the preceding call in the chain [eslint-plugin-drizzle/src/enforce-update-with-where.ts:38-39](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L38-L39).
> Sources: [eslint-plugin-drizzle/src/enforce-update-with-where.ts:38-39](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/enforce-update-with-where.ts#L38-L39)

## AST Member Resolution Utilities

### Path Traversal and Drizzle Object Matching

The plugin provides internal utility functions in `eslint-plugin-drizzle/src/utils/ast.ts` and `eslint-plugin-drizzle/src/utils/options.ts` to inspect Abstract Syntax Tree (AST) nodes for database instance matching and call-chain resolution. The `resolveMemberExpressionPath` function traverses a `TSESTree.MemberExpression` node upward through its object references, accumulating a dot-separated string representation of the call chain [eslint-plugin-drizzle/src/utils/ast.ts:3-37](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/ast.ts#L3-L37).

```typescript
export const resolveMemberExpressionPath = (node: TSESTree.MemberExpression) => {
	let objectExpression = node.object;
	let fullName = '';

	const addToFullName = (name: string) => {
		const prefix = fullName ? '.' : '';
		fullName = `${name}${prefix}${fullName}`;
	};

	while (objectExpression) {
		if (objectExpression.type === 'MemberExpression') {
			if (objectExpression.property.type === 'Identifier') {
				addToFullName(objectExpression.property.name);
			}
			objectExpression = objectExpression.object;
		} else if (objectExpression.type === 'CallExpression' && objectExpression.callee.type === 'Identifier') {
			addToFullName(`${objectExpression.callee.name}(...)`);
			break;
		} else if (objectExpression.type === 'CallExpression' && objectExpression.callee.type === 'MemberExpression') {
			if (objectExpression.callee.property.type === 'Identifier') {
				addToFullName(`${objectExpression.callee.property.name}(...)`);
			}
			objectExpression = objectExpression.callee.object;
		} else if (objectExpression.type === 'Identifier') {
			addToFullName(objectExpression.name);
			break;
		} else if (objectExpression.type === 'ThisExpression') {
			addToFullName('this');
			break;
		} else {
			break;
		}
	}

	return fullName;
```
Sources: [eslint-plugin-drizzle/src/utils/ast.ts:3-37](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/ast.ts#L3-L37)

> [!NOTE]
> During AST traversal, `resolveMemberExpressionPath` specifically intercepts identifiers, `ThisExpression` nodes, member expressions, and call expressions, appending `(...)` syntax to method calls before breaking or continuing path reduction [eslint-plugin-drizzle/src/utils/ast.ts:12-35](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/ast.ts#L12-L35).
> Sources: [eslint-plugin-drizzle/src/utils/ast.ts:12-35](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/ast.ts#L12-L35)]

### Configuration and Object Name Validation

Configured database object names are validated against AST nodes using `isDrizzleObj` and `isDrizzleObjName` [eslint-plugin-drizzle/src/utils/options.ts:3-41](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L3-L41). The rule options schema accepts a `drizzleObjectName` parameter configured as either a single string or an array of strings [eslint-plugin-drizzle/src/utils/options.ts:3-5](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L3-L5). If the array is empty, all object names are matched by default [eslint-plugin-drizzle/src/utils/options.ts:12-15](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L12-L15).

```typescript
export type Options = readonly [{
	drizzleObjectName: string[] | string;
}];

const isDrizzleObjName = (name: string, drizzleObjectName: string[] | string) => {
	if (typeof drizzleObjectName === 'string') {
		return name === drizzleObjectName;
	}

	if (Array.isArray(drizzleObjectName)) {
		if (drizzleObjectName.length === 0) {
			return true;
		}

		return drizzleObjectName.includes(name);
	}

	return false;
};
```
Sources: [eslint-plugin-drizzle/src/utils/options.ts:3-21](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L3-L21)

The `isDrizzleObj` function evaluates the structure of a `MemberExpression` node's object property to determine if it originates from a recognized database instance identifier or chained expression [eslint-plugin-drizzle/src/utils/options.ts:23-41](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L23-L41).

```typescript
export const isDrizzleObj = (
	node: TSESTree.MemberExpression,
	options: Options,
) => {
	const drizzleObjectName = options[0].drizzleObjectName;

	if (node.object.type === 'Identifier') {
		return isDrizzleObjName(node.object.name, drizzleObjectName);
	} else if (node.object.type === 'MemberExpression' && node.object.property.type === 'Identifier') {
		return isDrizzleObjName(node.object.property.name, drizzleObjectName);
	} else if (node.object.type === 'CallExpression') {
		if (node.object.callee.type === 'Identifier') {
			return isDrizzleObjName(node.object.callee.name, drizzleObjectName);
		} else if (node.object.callee.type === 'MemberExpression' && node.object.callee.property.type === 'Identifier') {
			return isDrizzleObjName(node.object.callee.property.name, drizzleObjectName);
		}
	}

	return false;
```
Sources: [eslint-plugin-drizzle/src/utils/options.ts:23-41](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L23-L41)

> [!TIP]
> Setting `drizzleObjectName` to an empty array (`[]`) in rule configurations bypasses strict name filtering, causing the plugin to evaluate query builder methods across all matching member expressions regardless of the base variable name [eslint-plugin-drizzle/src/utils/options.ts:12-15](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L12-L15).
> Sources: [eslint-plugin-drizzle/src/utils/options.ts:12-15](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/eslint-plugin-drizzle/src/utils/options.ts#L12-L15)

## Related

- [Query Builder Foundation](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/core-architecture/query-builder-foundation)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/llms.txt) for all pages in this wiki.
