Skip to content

docs: accurately describe config file traversal and add 401 troublesh… - #58057

Open
yanghonggang wants to merge 1 commit into
anomalyco:devfrom
yanghonggang:docs-config-traversal
Open

yanghonggang wants to merge 1 commit into
anomalyco:devfrom
yanghonggang:docs-config-traversal

Conversation

@yanghonggang

@yanghonggang yanghonggang commented Oct 22, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #58055

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The config docs say project config lookup "traverses up to the nearest Git directory". That is inaccurate in two ways: outside a Git repository the walk continues all the way up to /, and every opencode.json/opencode.jsonc found along the way is merged (nearer files win), not just the first one found.
I hit this in practice: a forgotten ~/opencode.json silently overrode the provider credentials in my global config for every non-Git directory under my home, producing a misleading 401 Unauthorized even though my API key was valid. It took strace to find the actual source of the wrong key.
Changes:

  • config page: describe the traversal as implemented (stops at the Git worktree root inside a repo; walks to / outside one; merges all files found), and add a caution about stray ancestor configs.
  • troubleshooting page: add the valid-key-but-401 case to "Authentication issues", pointing at ancestor config files, opencode debug config, and OPENCODE_DISABLE_PROJECT_CONFIG=1.
    The wording matches the implementation: project config files are collected by walking up from the cwd to the worktree root (packages/opencode/src/config/paths.ts), and non-Git directories use / as the worktree (packages/opencode/src/project/instance-context.ts).

How did you verify your code works?

Docs-only change; verified the behavior the text describes with a minimal repro script (attached in #58055): an ancestor opencode.json overriding a marker value wins when the cwd is not in a Git repo, and is ignored after git init. Ran it on 1.14.48 and 1.19.3 (current @latest), same result on both. Also checked the new :::caution block against existing directives in the same file.

Screenshots / recordings

N/A - documentation-only change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Oct 22, 2026

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correcting the outdated "traverses up to the nearest Git directory" line is a good idea, but the new text describes v1 behaviour, not v2. I checked it against the v2 loader (packages/core/src/config/discovery.ts). There, project config discovery walks the current directory and every ancestor up to the filesystem root, whether or not you are inside a Git repository. Nothing stops at the worktree root. The built-in skill doc (packages/core/src/plugin/skill/opencode.md, updated in #45681) already says this. As written, the config page, the caution box and the troubleshooting item would mislead v2 users who are inside a repo into thinking an ancestor ~/opencode.json can't affect them.

The rest checks out: opencode debug config and OPENCODE_DISABLE_PROJECT_CONFIG both exist in v2, and nearer files do take precedence. One nuance on precedence: every discovered .opencode/opencode.json(c) overrides every plain opencode.json(c).

Public API: unchanged (docs only).

Related: #55909

:::

When OpenCode starts up, it first looks for a config file in the current directory, then traverses up to the nearest Git directory.
When OpenCode starts up, it looks for `opencode.json` / `opencode.jsonc` starting in the current directory and walking up the directory tree. Inside a Git repository, the walk stops at the Git worktree root. Outside a Git repository, it continues all the way up to the filesystem root (`/`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In v2 the walk doesn't stop at the Git worktree root: ConfigDiscovery.discover calls fs.up with no stop, so it always continues to /, inside repos too. Could this say it checks the current directory and every ancestor up to the filesystem root, including directories above the repository root? It could also mention that .opencode/opencode.json(c) files override plain opencode.json(c) files (see packages/core/src/plugin/skill/opencode.md).

Since the walk ignores Git boundaries in v2, a stray ~/opencode.json applies to every directory below it, Git repos included, not only to non-Git directories.

1. Try re-authenticating with the `/connect` command in the TUI
2. Check that your API keys are valid
3. Ensure your network allows connections to the provider's API
4. If you get `401 Unauthorized` but your API key is valid (for example, `curl` with the same key succeeds), check for a stray `opencode.json` / `opencode.jsonc` in an ancestor directory of your working directory. OpenCode merges config files found while walking up the directory tree - outside a Git repository, all the way up to `/` - and an ancestor config can override the credentials in your global config. Run `opencode debug config` to inspect the resolved configuration, and audit ancestor directories (especially your home directory) for forgotten config files. You can also set `OPENCODE_DISABLE_PROJECT_CONFIG=1` to skip project config discovery.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: the "outside a Git repository" qualifier doesn't hold in v2. The walk always reaches /, so an ancestor config can override credentials inside a repo too.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Oct 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant