CodeCharter reports a finding. What now? Three responses are possible: fix it, deliberately suppress it, or disable the rule if it does not fit your team.
Reading a finding
Example output:
--- Warning (1) ---
WARN [Testability] Direct DateTime/DateTimeOffset usage instead of TimeProvider
PricingEngine.Calculate
Acme.Domain/Calculations/PricingEngine.cs:42
↳ Inject TimeProvider via constructor and call GetUtcNow() or GetLocalNow(). For testing, use Microsoft.Extensions.Time.Testing.FakeTimeProvider
This tells you:
- Severity: findings are grouped by severity (
--- Warning (1) ---), and each finding starts with a tag likeWARN - Category and rule name:
[Testability]followed by the rule's display name. The rule's slug isdatetime-direct-usage(the rule file name); you need it for suppressions and configuration, and it is searchable in the wiki. - Affected code: the entity (
PricingEngine.Calculate) plus file and line below it - Recommendation: the line starting with
↳. The full rule description is included in thejsonoutput.
Option A: fix it
Before:
public class PricingEngine
{
public decimal Calculate(decimal basePrice)
{
var now = DateTime.UtcNow;
if (now.DayOfWeek == DayOfWeek.Sunday) return basePrice * 1.5m;
return basePrice;
}
}
After:
public class PricingEngine
{
private readonly TimeProvider _time;
public PricingEngine(TimeProvider time) => _time = time;
public decimal Calculate(decimal basePrice)
{
var now = _time.GetUtcNow();
if (now.DayOfWeek == DayOfWeek.Sunday) return basePrice * 1.5m;
return basePrice;
}
}
Test:
[Fact]
public void Sunday_Price_Is_Surcharged()
{
var clock = new FakeTimeProvider();
clock.SetUtcNow(new DateTimeOffset(2024, 1, 7, 12, 0, 0, TimeSpan.Zero)); // Sunday
var engine = new PricingEngine(clock);
engine.Calculate(100m).Should().Be(150m);
}
On the next codecharter analyze run the finding is gone.
Option B: deliberately suppress it
Sometimes you have a good reason not to follow the rule at a particular location — for example in a migration class that is historical and should not be touched.
Inline suppression directly in the code — on the same line:
var migrationTimestamp = DateTime.UtcNow; // codecharter-disable datetime-direct-usage
Or on the line above the statement:
// codecharter-disable datetime-direct-usage
var migrationTimestamp = DateTime.UtcNow;
Or using codecharter-disable-next-line to be explicit that it covers only the
following line:
// codecharter-disable-next-line datetime-direct-usage
var migrationTimestamp = DateTime.UtcNow;
Multiple rule slugs are space-separated, and the slug must match exactly
(lowercase). A // codecharter-disable without a slug is not a per-line
suppression: on a line of its own it suppresses every finding in the entire
file. More details under Suppressions.
Option C: disable the rule
If you do not want a rule in your entire repo, switch it off centrally instead of suppressing it at every call site.
To switch a rule off across the repository, add an ignore entry to your
.codecharter/config.yml:
version: 1
ignore:
- rule: datetime-direct-usage
Add in: or match: to limit the suppression to a namespace or to matching
entity names. As a middle ground you can keep the rule but lower its severity
instead, with an overrides entry (severity: error, warning, or info).
See Configuration file for the full set of
sections.
A file-level // codecharter-disable comment also exists, but it suppresses
every rule in that file, not just one. For more options see
Suppressions.
Only do this if the rule genuinely does not fit your team, not to avoid a single location. For a specific location, inline suppression is the right choice.
Order of response
Rule of thumb:
- First consider whether the finding is correct. If it conflicts with your explicit architecture decision, the rule is wrong for you. Then use option C.
- If the rule is correct but the location is a genuine exception: option B with a reason in the comment.
- Otherwise: option A. If you have to silence a finding without a real decision behind it, the tooling quickly becomes worthless.
Pre-existing findings: use a baseline
When you introduce CodeCharter to an existing codebase, you do not have to fix or suppress every pre-existing finding right away. Record them in a baseline:
codecharter analyze MySolution.sln --write-baseline codecharter-baseline.json
Later runs with --baseline codecharter-baseline.json report only findings
that are not in the baseline.
Findings as a file
codecharter analyze MySolution.sln --output json --output-file findings.json
analyze takes the path to your .sln, .slnx, or .csproj file.
This lets you process findings further in your PR system, map them
to tickets, or track a trend. Format details under
Output formats.