anomalyco / anomalyco/opencode

Bug: configuring clang-format, air or uv by name silently disables the formatter

Open
#46,868 4 comments 0 reactions 1 assignee View on GitHub

@nexxeln is already working on this.

Since Sep 2, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

Configuring clang-format, air or uv in the formatter section silently turns that formatter off. The name works for disabled: true, but any other override kills it.

packages/opencode/src/format/index.ts:134 looks up the built-in with Formatter[name as keyof typeof Formatter], where name is the config key. That reads the module's export identifier, not the formatter's published name. Three built-ins differ between the two:

config key, as the docs publish it export identifier in format/formatter.ts
clang-format clang
air rlang
uv uvformat

For those three the lookup returns undefined. The next lines then build the entry from builtIn ?? { extensions: [] } and set enabled to async () => info.command ?? false. With no command in the config, enabled always returns false, and the built-in extensions are replaced by an empty list. The formatter is gone.

The published name is the right key. formatters is already keyed by item.name at index.ts:130, status() reports item.name, and docs/formatters.mdx lists clang-format, air and uv in its Built-in table. The docs also say "You can configure built-in formatters with options like environment or extensions", which is the case that breaks.

Steps to reproduce
  1. Put this in opencode.json:
{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "clang-format": {
      "environment": { "CLANG_FORMAT_STYLE": "file" }
    }
  }
}
  1. Run opencode and inspect the formatter status.

clang-format reports extensions: [] and enabled: false. Writing a .c file does not format it. Removing the clang-format block restores the formatter, so adding an override is what disables it.

The same happens with air and with uv. A correctly named built-in such as gofmt is not affected, because its export identifier and its name match.

Measured

Added to packages/opencode/test/format/format.test.ts on ef27925, with Formatter.clang pointed at a scratch extension and a command that appends C:

config: { formatter: { "clang-format": {} } }
file contents after Format.file()   expected "xC"   actual "x"

The command never runs. The same config for all three names makes status() return an empty extensions list for each, instead of the built-in list.

OpenCode version

Built from source at ef27925.

Operating System

macOS 26.6.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.