Resolve Conflicting Formatting Rules Before Saving a File

Test which editor, project and formatter rule controls the actual saved bytes, using a minimal fixture instead of assuming every configuration shares precedence.

Formatting precedence determines which supported rule produces saved file bytes in a particular environment. Consistent whitespace is an output property, not proof of functional correctness.

Substantively revised October 21, 2026. Author interpretation, documented cases and hypothetical examples are distinguished below.

The indentation changes when the file is saved, then changes again when another person formats it. Both people can point to a setting that says they are right. The disagreement may have little to do with preference: different tools can read different scopes, select different configurations or execute in a different order.

Direct answer

Identify the exact file, its language mode, the formatter that actually runs and the configuration that formatter resolves. Distinguish editor settings, EditorConfig rules and formatter configuration rather than treating them as one universal hierarchy. Reproduce the disagreement on a tiny disposable fixture, compare the output, then correct the responsible rule. Run normal tests separately; consistent formatting does not establish functional correctness.

This article proposes a Formatting Route Trace for investigating conflicting formatting behavior. It is an author-designed debugging method, not a new configuration standard. Its acceptance question is whether the same intended formatting route produces an explainable result for the same file under recorded conditions. It does not authorize formatting an entire repository to make one example look consistent.

Key takeaways

Start with the file path and action that produced the change. Format Document, format on save and a command-line formatter are different routes until evidence shows that they use the same tool and settings. A screenshot of an indentation preference does not identify the route that rewrote the file.

Keep precedence rules attached to their system. EditorConfig's nearer-file behavior does not define every editor's setting hierarchy. VS Code's language-specific settings can defeat a simple workspace always wins explanation. A formatter can also interpret supported configuration properties through its own documented rules.

Use a small fixture that exposes the disputed property. A nested object can reveal indentation; a short line usually cannot reveal a wrapping threshold. Keep the fixture's starting bytes stable so that a changed result can be attributed to a controlled difference rather than a different input.

Separate appearance, bytes and behavior. A tab can display at a chosen width while remaining a tab character. Different line endings can create a large diff without changing the visible text. Formatting checks and program tests answer different questions and should produce separate evidence.

Observation: two correct settings can belong to different routes

A developer changes a workspace indentation setting and expects it to settle a formatting disagreement. Saving still produces the old result. Another developer edits a formatter configuration and sees an immediate change. Neither observation proves that workspace settings are broken; the active formatter may be using its own resolved configuration.

The recurring pattern is misplaced authority. A setting looks close to the file in the interface, so it feels like the controlling rule. But interface proximity is not configuration precedence. The system that performs the rewrite decides which inputs matter, and the invocation determines which system actually runs.

Define a route as a particular action through a particular tool to a resulting file. Define scope as the context in which a setting applies. Define resolution as the tool's process for choosing applicable values. A route can cross several systems without making their rules interchangeable.

The reader's useful outcome is an explanation that survives the next save. Manually correcting spaces can remove the visible symptom while leaving the conflicting route intact. Tracing the route makes it possible to decide whether to change a setting, select a formatter or repair the integration that runs it.

Root cause: configuration precedence is local to a system

A repository can contain EditorConfig, a formatter configuration and editor workspace settings at the same time. They can cooperate, but their coexistence does not define a single global ordering. Some properties are translated, some are unsupported and some are overridden by a more specific configuration in the system performing the action.

There is also a distinction between a configured value and an executed action. Selecting a formatter does not prove that format on save ran. Seeing a changed file does not prove that only one save-time participant changed it. A later action can obscure the result of an earlier one.

Tool versions and environment add another boundary. A command resolved from the system path may differ from the project's installed formatter. An editor profile can carry settings another profile lacks. An explanation that omits these conditions can work on one computer while remaining irreproducible elsewhere.

The right level of detail depends on the discrepancy. If the question concerns indentation, inspect indentation-related inputs first. If the command fails to parse the fixture, that is a tool or input problem before it is a formatting disagreement. Do not treat every different result as an argument over style.

Three documented examples and what they establish

EditorConfig documents a search through directories and a root boundary. Within its matching rules, later applicable properties and closer files can take precedence. That behavior depends on applicable editor or plugin support; it is not a promise that every other formatter reads every property identically. [S1]

VS Code documents language-specific settings that can override non-language-specific settings even at a narrower ordinary scope. Its settings hierarchy also includes policy settings. This is a concrete reason to avoid the claim that workspace settings always win. Inspect the actual language and setting scope before changing a seemingly more local value. [S2]

Prettier documents its configuration resolution and support for mapping particular EditorConfig properties. Its own configuration can override those mapped choices, and its EditorConfig search stops at the project root. This is a formatter-specific relationship, not evidence that every EditorConfig property is enforced or that all formatters share this behavior. [S3]

These examples are official descriptions of different configuration mechanisms. They do not establish which tool ran in a particular editor session. That last question requires observing the actual route and reproducing its output under known conditions.

Framework: the Formatting Route Trace

Trace Input, Invocation, Resolution and Result. These four components form the author's method. Their purpose is to keep a disagreement tied to observable evidence rather than collect an impressive inventory of configuration files that may never participate in the route.

Input identifies the exact file path, starting contents and relevant language. The path matters because configuration lookup can depend on it. The starting contents matter because a formatter may already consider a simple fixture acceptable. A test that cannot express the disputed property provides little evidence about that property.

Invocation identifies the action and executable. Record whether the route is an editor command, a save operation or an explicit command-line call. Where version differences could matter, record the installed version actually used. Avoid an unpinned download merely to make a local example run; that introduces another moving input.

Resolution identifies the configuration sources that the active tool actually considers. Read the applicable rule for that tool, inspect the relevant scopes and use supported inspection facilities where available. A file existing in the repository is not proof that the tool loaded it for this path.

Result identifies the exact changed bytes and the interpretation of that change. Show a small before-and-after comparison and explain whether the discrepancy concerns indentation, wrapping, line endings or a failure to run. A count of changed lines alone can conceal the property that matters.

Control one variable at a time while investigating. If both formatter selection and configuration change together, a different output cannot identify which correction mattered. Restore the small fixture's starting contents between comparisons so the second route does not merely inherit the first route's output.

The acceptance statement should name the route and scope: the recorded formatter, invoked for this path under these applicable settings, produces the intended fixture. Broaden that conclusion only after checking the additional file types and routes you actually need. One JavaScript specimen does not approve every language in a repository.

A reproducible specimen before touching project files

Use a disposable fixture in an authorized test location that has the configuration relationships you intend to examine. For an indentation dispute, choose a small parseable file containing a nested structure. Keep a known original copy so that each route receives identical input. This is a proposed procedure, not a claim that a test has already run in the reader's project.

Make the expected difference visible in a text comparison. For example, imagine a line with two leading spaces before a property and a second line nested another level. If a test route changes the first to four leading spaces and the second accordingly, record that concrete difference. The invented widths illustrate the dispute; they are not a preferred team standard.

Represent invisible characters explicitly when needed. A visual alignment can be produced by a tab or several spaces, and the editor's tab display width can make them look similar. A text or byte-aware comparison prevents a display preference from being mistaken for an actual rewrite.

For wrapping, include a suitable expression whose length and syntax can expose the chosen formatter's behavior. Do not assume that every formatter's width setting is a hard maximum for every construct. Inspect the actual result and its documentation rather than counting characters and declaring the tool defective.

If the intended route has a supported check-only mode, prefer that for detecting differences before any write. A check result still needs interpretation: a formatting difference and a tool error are different outcomes. Use the documentation for the selected executable rather than transferring flags or exit-code meanings from another tool.

Only after the fixture explains the conflict should you consider a project configuration change. Review the resulting diff for the intended property and scope. A repository-wide rewrite obscures the original diagnosis and makes unrelated changes harder to assess.

Hypothetical case study: four spaces become two on save

Consider an invented project with a root EditorConfig rule requesting four-space indentation for a particular file type. A formatter configuration requests a width of two spaces. A developer sees the EditorConfig value, types a nested example accordingly and saves. The output uses two spaces.

Those figures are synthetic case values, not performance measurements or style recommendations. The example assumes that the active formatter is Prettier and that the configuration applies to the fixture. The review must establish those assumptions in a real project before applying the explanation.

The developer first records the exact fixture path and starting contents. They identify the formatter used by the relevant editor route instead of relying on a status-bar indentation display. They also distinguish pressing Save from explicitly choosing a formatting command, because the two actions need not execute the same sequence.

The resolution step then asks whether the formatter's own configuration is being loaded and whether it overrides mapped EditorConfig indentation. Under the stated hypothetical conditions, that documented relationship explains the result. Changing only the editor's visual tab width would not repair the underlying disagreement about exported file bytes.

The team chooses a single intended indentation for this scope and updates the conflicting configuration accordingly. The choice itself is a team requirement, not something proved by the formatter documentation. The documentation explains how to implement the choice; it does not decide whether two or four is better for the project.

Next, a second developer reports that saving still differs. The team compares routes before changing another setting. Suppose this developer's language-specific setup selects a different formatter. That new fact concerns invocation rather than the first formatter's resolution. Correcting it is a separate action with its own retest.

The fixture is restored to its original contents and each intended route is tested again. The team retains the small output comparison and the actual tool version used. They then run the project's relevant tests separately, because agreeing on indentation does not prove that the application behaves correctly.

The example contains two distinct conflicts: competing configuration values within the first route and a different tool in the second route. The method makes those conflicts distinguishable. It does not claim that every save-time discrepancy has those causes or that a consistent specimen approves every file in the project.

Failure example: fixing the screenshot instead of the file

A developer changes tab display width until the editor's text appears aligned with a colleague's screenshot. The screenshot now looks right, but a text comparison still shows different indentation characters. The supposed fix changed presentation without establishing the desired file content.

Another developer responds to a noisy formatting diff by running a formatter across the entire repository. The immediate file looks consistent afterward, but the change also touches unrelated content and gives reviewers no clear account of the original route. A large diff is not a substitute for a successful diagnosis.

Repair the smallest relevant boundary. If display width was the issue, document that distinction. If the wrong formatter ran, correct the invocation. If an applicable formatter configuration overrides a mapped setting, reconcile the intended source of that value. Re-run the fixture before broadening the change.

Tradeoff and counterargument: consistency has a scope

A team can reasonably prefer a formatter's defaults over a large set of custom settings. Fewer choices may make configuration easier to explain. That preference does not eliminate the need to know which formatter runs or which project configuration it loads. Simplicity is a design choice, not evidence of execution.

A counterargument is that continuous integration already checks formatting, so local investigation is unnecessary. Keep the CI check, but identify whether it uses the same version, file scope and route as the editor. A failing check can reveal disagreement without explaining why the local save produced a different result.

There is also a cost to enforcing one rule across every file. Generated files, vendored material or specialized languages may have different handling. Use the project's actual policy and supported configuration mechanisms. Do not make exclusions merely to hide a failing check, and do not assume universal formatting is always the correct scope.

Finally, consistent formatting can make review easier without establishing semantic safety. A formatter may parse and rewrite text while leaving a logical bug untouched. Keep functional tests, content checks and human review connected to their own requirements instead of treating a formatting pass as a complete quality gate.

Common mistakes

Editing every configuration file at once removes the ability to explain the result. Begin with the active route and change the responsible input. Keep unrelated preferences out of the diagnosis unless an observation shows they participate in the same failure.

Assuming a nearby file always wins confuses systems. A nearer EditorConfig file has meaning inside that mechanism; an editor's language-specific setting and a formatter's configuration have their own rules. Name the applicable system when explaining precedence.

Ignoring the exact path can make two fixtures look equivalent when their configuration lookup differs. Keep the file location and working environment in the reproduction notes. A copied snippet in an unrelated scratch file may test a different route.

Treating check-only failures as proof of an unformatted file can conceal execution problems. Read the tool's result and supported exit semantics. Missing configuration, parsing failure or a missing executable is not the same observation as a successful check that found a formatting difference.

Using a clean formatting diff to approve unrelated changes also exceeds the evidence. Review the actual behavioral change and run relevant tests. A formatter can settle whitespace without settling a disputed algorithm, content claim or data transformation.

Action plan

Pick one file with a reproducible formatting disagreement and record its path, initial bytes and language. Identify the exact action that changes it. Do not begin with a repository-wide rewrite or an assumption that the most visible setting is authoritative.

Create a small fixture exposing the disputed property and identify the tool and version actually used. Resolve the applicable configuration through that tool's documented rules. Compare output from equivalent starting contents and separate presentation differences from actual byte changes.

Correct the narrow cause, repeat the intended routes and review the resulting diff. Run the project's normal tests as a separate step. Retain enough reproduction detail that another maintainer can distinguish a future tool-version change from a configuration or integration change.

FAQ

Does a workspace setting always override a user setting?

No universal rule applies across systems. VS Code documents language-specific precedence that complicates that shortcut. Inspect the relevant setting, scope and language rather than relying on proximity alone.

Does EditorConfig control every formatter?

No. Support and property mapping depend on the tool or integration. Verify what the active formatter reads and what its own configuration can override.

Why record the exact file path?

Configuration resolution can depend on location. Two identical snippets in different directories may receive different applicable rules, so contents alone do not define the reproduction.

Is tab width the same as indentation characters?

No. Displaying a tab at a chosen width does not turn it into that many spaces. Inspect the actual characters when the disagreement concerns file content.

Can format on save differ from Format Document?

Treat them as separate routes until verified. Their surrounding actions or selected tool can differ in a real setup; inspect the actual execution rather than assuming equivalence.

Should I delete EditorConfig when using Prettier?

Not automatically. The mechanisms can cooperate. Reconcile the intended rules and supported mappings before removing a configuration that other tools may still use.

Does Prettier enforce every EditorConfig property?

Do not assume it does. Its documentation describes particular mappings and limitations. Read those for the installed route instead of treating all properties as interchangeable options.

Why pin the formatter for a reproduction?

It reduces uncertainty about which implementation produced the output. Record the actual version and environment rather than silently substituting a globally installed or newly downloaded tool.

Must the fixture be inside the real project?

It needs the relevant configuration relationships, but should be safely disposable. A fixture in an unrelated directory may not reproduce lookup; a production file is unnecessary for the initial investigation.

Can I infer success from no visible change?

Not alone. The tool might not have run, or the fixture might not expose the disputed property. Confirm execution and use an input capable of revealing the difference.

Is a check-only error a formatting difference?

Not necessarily. Inspect the selected tool's documented result and diagnostics. A parser or execution error should not be relabeled as a normal style disagreement.

Should a formatting fix change program behavior?

That requires separate scrutiny. Review any semantic change rather than hiding it inside a style correction, and run the appropriate tests for the actual modification.

Does one passing JavaScript specimen approve Markdown too?

No. Different language routes can use different parsers, settings or tools. Extend the evidence to the additional file type before making a broader claim.

What if CI and the editor disagree?

Compare executable versions, file scope, applicable configuration and invocation. Keep the failing evidence while locating the difference rather than weakening the check to make it green.

Does formatting consistency prove the repository is healthy?

No. It supports one narrow presentation requirement. Functional behavior, source accuracy, content quality and deployment correctness still require their own evidence.

Recommended books

David Thomas and Andrew Hunt's The Pragmatic Programmer, 20th Anniversary Edition: your journey to mastery provides context for deliberate tool use and reproducible engineering habits. Its role here is broader reasoning about a workflow; it does not document the current precedence of VS Code or Prettier settings.

Steve McConnell's Code Complete, second edition, is a useful broader reference on software construction and readable code. Read it as context for making changes understandable and reviewable, while using the actual formatter's documentation for configuration semantics.

Don Norman's The Design of Everyday Things, revised and expanded edition, helps frame the difference between a control's apparent meaning and the feedback an action produces. That perspective is useful when an indentation display and a save-time rewrite seem to disagree; it is not evidence that a particular extension executed.

Further exploration

Find one local formatting command and its CI counterpart. Compare the exact tool version, target file path and resolved configuration before comparing the resulting text. A small documented agreement is more useful than a general claim that everyone uses the same settings.

If the routes differ intentionally, explain why and which output is authoritative for the project. If they differ accidentally, repair the smallest responsible boundary and preserve the fixture as a regression example appropriate to that integration. Keep the conclusion tied to formatting rather than expanding it into a claim about program correctness.

Primary evidence sources

Related concepts: systems thinking, wealth structure, and the survival loop. Read the editorial policy and citation guide.