AvoidDriftInsertMissingConflictTargetRule class
Warns when a Drift insert targets a table with a UNIQUE @TableIndex
on a non-primary-key column and does not pass a matching
onConflict: DoUpdate(target: [uniqueCol]).
Since: v12.3.4 | Rule version: v1
Drift tables declaring @TableIndex(..., unique: true) on a non-PK column
need an explicit conflict target on every batch.insert(...) /
into(table).insert(...). Without target:, SQLite falls back to
ON CONFLICT("id") — the primary key — and misses the real UNIQUE
constraint. The insert succeeds for new rows and raises
SqliteException(2067): UNIQUE constraint failed the moment the unique
value (UUID, email, etc.) already exists on disk or appears twice in one
batch. The crash is usually discovered late: mid-way through a static-data
import, after a debugger() in debugException has silently frozen the
isolate. The hazard is invisible at the call site because the table's
annotation lives in a different file from the IO method.
The rule scans the current compilation unit for @TableIndex(unique: true)
annotations on non-PK columns, then flags any insert, insertAll, or
insertOnConflictUpdate call against those tables that does not either:
- pass
onConflict: DoUpdate(target: [<UNIQUE col>])/DoUpdate.withExcluded(target: [...])referencing at least one of the UNIQUE columns, or - use
mode: InsertMode.replace(explicit REPLACE is an acceptable alternative).
insertOnConflictUpdate without an explicit target: is ALWAYS flagged
against a UNIQUE-indexed non-PK column — the method looks safe but
defaults to ON CONFLICT("id") and misses the real UNIQUE index.
BAD:
@TableIndex(name: 'idx', columns: {#uuid}, unique: true)
class ContactPoints extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get uuid => text()();
}
Future<void> putAll(AppDatabase db, List<ContactPointsCompanion> rows) async {
await db.batch((batch) {
for (final row in rows) {
batch.insert(db.contactPoints, row); // UNIQUE(uuid) will raise 2067
}
});
}
GOOD:
Future<void> putAll(AppDatabase db, List<ContactPointsCompanion> rows) async {
await db.batch((batch) {
for (final row in rows) {
batch.insert(
db.contactPoints,
row,
onConflict: DoUpdate(
(_) => row,
target: [db.contactPoints.uuid],
),
);
}
});
}
- Inheritance
-
- Object
- SaropaLintRule
- AvoidDriftInsertMissingConflictTargetRule
Constructors
Properties
- accuracyTarget → AccuracyTarget?
-
Optional accuracy target for this rule (for documentation and tooling).
Does not enforce; used by reports and rule-audit scripts.
no setterinherited
-
applicableFileTypes
→ Set<
FileType> ? -
The file types this rule applies to.
no setterinherited
- canUseParsedResult → bool
-
Indicates whether this analysis rule can work with just the parsed
information or if it requires a resolved unit.
no setterinherited
-
certIds
→ List<
String> -
CERT coding standard identifiers (e.g. STR02-C). Populate only where
there is a clear mapping; leave empty for most rules initially.
no setterinherited
- code → LintCode
-
The lint code for this rule.
no setterinherited
-
configAliases
→ List<
String> -
Alternate config keys that can be used to reference this rule.
no setterinherited
-
conflictingRules
→ List<
String> -
Curated opposite/competing rule names.
no setterinherited
- cost → RuleCost
-
The estimated execution cost of this rule.
no setteroverride
-
cweIds
→ List<
int> -
CWE identifiers this rule helps prevent or detect.
https://cwe.mitre.org/ — e.g. CWE-798 (Hardcoded Credentials).
no setterinherited
- description → String
-
Short description suitable for display in console output and IDEs.
finalinherited
- diagnosticCode → DiagnosticCode
-
The code to report for a violation.
no setterinherited
-
diagnosticCodes
→ List<
DiagnosticCode> -
The diagnostic codes associated with this analysis rule.
no setterinherited
- documentationUrl → String
-
Returns the documentation URL for this rule.
no setterinherited
- effectiveSeverity → DiagnosticSeverity?
-
Get the effective severity for this rule, considering overrides.
no setterinherited
- exampleBad → String?
-
Short code example that VIOLATES this rule (shown in CLI walkthrough).
no setterinherited
- exampleGood → String?
-
Short code example of COMPLIANT code (shown in CLI walkthrough).
no setterinherited
-
fixGenerators
→ List<
SaropaFixGenerator> -
Fix producer generators for this rule.
no setterinherited
- hashCode → int
-
The hash code for this object.
no setterinherited
- hyphenatedName → String
-
Returns the rule name in hyphenated format for display.
no setterinherited
- impact → LintImpact
-
The business impact of this rule's violations.
no setteroverride
-
incompatibleRules
→ List<
String> -
A list of incompatible rule names.
no setterinherited
- isDisabled → bool
-
Check if this rule is disabled via configuration.
no setterinherited
- maximumLineCount → int
-
Maximum line count for this rule to run.
no setterinherited
- minimumLineCount → int
-
Minimum line count for this rule to run.
no setterinherited
- name → String
-
The rule name.
finalinherited
- owasp → OwaspMapping?
-
OWASP categories this rule helps prevent.
no setterinherited
- pubspecVisitor → PubspecVisitor?
-
A visitor that visits a
Pubspecto perform analysis.no setterinherited -
Curated "see also" rule names for discoverability in docs/IDE tooling.
no setterinherited
- reporter ← DiagnosticReporter
-
Sets the
DiagnosticReporterfor theCompilationUnitcurrently being visited.no getterinherited -
requiredPatterns
→ Set<
String> ? -
String patterns that must be present in the file for this rule to run.
no setterinherited
- requiresAsync → bool
-
Whether this rule only applies to async code.
no setterinherited
- requiresBlocImport → bool
-
Whether this rule only applies to files that import Bloc.
no setterinherited
- requiresClassDeclaration → bool
-
Whether this rule only applies to files with class declarations.
no setterinherited
- requiresFlutterImport → bool
-
Whether this rule only applies to files that import Flutter.
no setterinherited
- requiresImports → bool
-
Whether this rule only applies to files with imports.
no setterinherited
- requiresMainFunction → bool
-
Whether this rule only applies to files with a main() function.
no setterinherited
- requiresProviderImport → bool
-
Whether this rule only applies to files that import Provider.
no setterinherited
- requiresRiverpodImport → bool
-
Whether this rule only applies to files that import Riverpod.
no setterinherited
- requiresWidgets → bool
-
Whether this rule only applies to Flutter widget code.
no setterinherited
- ruleStatus → RuleStatus
-
Lifecycle status. Default RuleStatus.ready. Use RuleStatus.beta for
new or heuristic-heavy rules; RuleStatus.deprecated for sunset.
no setterinherited
- ruleType → RuleType?
-
Semantic type of this rule. Default
null= unspecified (legacy). When set, used for quality gates, accuracy targets, and reporting.no setteroverride - runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- skipExampleFiles → bool
-
Whether to skip example files (example/**).
no setterinherited
- skipFixtureFiles → bool
-
Whether to skip fixture files (fixture/, fixtures/).
no setterinherited
- skipGeneratedCode → bool
-
Whether to skip generated files (*.g.dart, *.freezed.dart, *.gen.dart).
no setterinherited
- skipTestFiles → bool
-
Whether to skip test files (*_test.dart, test/**).
no setterinherited
- state → RuleState
-
The state of this analysis rule.
finalinherited
-
supersedesRules
→ List<
String> -
Rule names this rule supersedes/replaces.
no setterinherited
-
Tags for filtering and discovery (e.g. in docs, IDE, or CI).
Examples: 'performance', 'accessibility', 'suspicious', 'convention'.
no setteroverride
- testRelevance → TestRelevance
-
How this rule relates to test files.
no setterinherited
- usesTypeResolution → bool
-
Whether this rule triggers lazy cross-library type resolution in the
analyzer (e.g.
.staticType,.library,.allSupertypes,.enclosingElement).no setterinherited
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
registerNodeProcessors(
RuleVisitorRegistry registry, RuleContext context) → void -
Registers node processors in the given
registry.inherited -
registerNodeProcessors2(
RuleVisitorRegistry2 registry, RuleContext context) → void -
Registers node processors in the given
registry.inherited -
reportAtNode(
AstNode? node, {List< Object> arguments = const [], List<DiagnosticMessage> ? contextMessages}) → Diagnostic? -
Reports a diagnostic at
nodewith messageargumentsandcontextMessages.inherited -
reportAtOffset(
int offset, int length, {List< Object> arguments = const [], List<DiagnosticMessage> ? contextMessages}) → Diagnostic -
Reports a diagnostic at
offset, withlength, with messageargumentsandcontextMessages.inherited -
reportAtPubNode(
PubspecNode node, {List< Object> arguments = const [], List<DiagnosticMessage> contextMessages = const []}) → Diagnostic -
Reports a diagnostic at Pubspec
node, with messageargumentsandcontextMessages.inherited -
reportAtSourceRange(
SourceRange sourceRange, {List< Object> arguments = const [], List<DiagnosticMessage> ? contextMessages}) → Diagnostic -
Reports a diagnostic at
sourceRange, with messageargumentsandcontextMessages.inherited -
reportAtToken(
Token token, {List< Object> arguments = const [], List<DiagnosticMessage> ? contextMessages}) → Diagnostic? -
Reports a diagnostic at
token, with messageargumentsandcontextMessages.inherited -
runWithReporter(
SaropaDiagnosticReporter reporter, SaropaContext context) → void -
Override this method to implement your lint rule.
override
-
shouldSkipFile(
String path) → bool -
Check if a file path should be skipped based on context settings.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited