avoid_default_tostring
This rule flags string interpolation of a value whose class does not override toString.
Why use this rule
Section titled “Why use this rule”Object.toString returns Instance of 'Foo'. That is the one piece of information the reader of a log already has — the type — and none of the information they need.
The cost lands exactly where it hurts most: an error message written to diagnose a failure, or a log line captured from production, that turns out to say nothing. By the time anyone notices, the incident is over and the data is gone.
class User { const User(this.id, this.email);
final String id; final String email;}
void logFailure(User user) { // Logs: "failed for Instance of 'User'" logger.severe('failed for $user');}class User { const User(this.id, this.email);
final String id; final String email;
@override String toString() => 'User(id: $id, email: $email)';}
void logFailure(User user) { logger.severe('failed for $user');}Or interpolate the fields you actually need:
logger.severe('failed for ${user.id}');Known limitations
Section titled “Known limitations”Only classes declared in the analysed code are reported. A type from the SDK or a third-party package without a toString is not something the user can fix, so it is skipped.
The check walks the full supertype chain, so a class inheriting toString from a base class is not flagged. Enums, records, and core types render usefully by default and are never reported.
Turning this rule off
Section titled “Turning this rule off”This rule is in the opinionated preset, so it is on with
preset: opinionated, or by name:
rules: avoid_default_tostring: trueTo turn it off again:
rules: avoid_default_tostring: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: avoid_default_tostring: report_enums: truerules: avoid_default_tostring: report_enums: true| Option | Type | Default | Description |
|---|---|---|---|
report_enums |
bool | false |
Also report interpolated enums without a toString override. Off by default because Status.active already reads well |
Related rules
Section titled “Related rules”avoid_accessing_other_classes_private_members— Make the underscore mean what everyone reads it as.avoid_commented_out_code— Detect and flag commented-out code.avoid_complex_conditions— Keep boolean conditions within an operand budget.avoid_deep_nesting— Keep control flow within a nesting budget.