Skip to content

config: instructions field does not load instruction files (v2.0.16) #51341

Closed

Description

@agilebean

Summary

A file referenced from the global config's instructions array is never added to a session's context, so shared rule files cannot be loaded from the config at all. A file reachable through AGENTS.md loads fine in the same session, so the config path is the broken one.

Environment

  • opencode version: 2.0.16 (homebrew opencode-v2)
  • OS: Darwin 25.6.0 (macOS, arm64)
  • Terminal: Unavailable: terminal environment variables are not set
  • Shell: /opt/homebrew/bin/bash
  • Install/channel: homebrew, release
  • Active plugins: @openchamber/opencode-claude@0.14.0 plus local openchamber plugins

Reproduction

  1. Put a marker file at $HOME/agentkit/RULES.md containing the single line MARKER-7391.
  2. In ~/.config/opencode/opencode.jsonc set "instructions": ["~/agentkit/RULES.md"].
  3. Restart opencode. Create a new session and ask: "Does your context contain the string MARKER-7391? Answer yes or no." -> No.
  4. Control in the same session: ask for a sentence from ~/.config/opencode/AGENTS.md -> Yes. Ask for a sentence from the agent definition -> Yes.

Path forms also tried, each after a restart, each negative: "$HOME/agentkit/RULES.md", an absolute path, and a config-dir-relative "RULES.md" with a symlink placed next to opencode.jsonc.

Expected Behavior

The referenced file's text is part of the session's instructions, exactly as AGENTS.md is.

Actual Behavior

The file is never loaded, for every path form tried. AGENTS.md from the same directory, and the agent prompt, are both present in the same session's context.

Additional Context

  • Verified in freshly created sessions with a control question, so this is not the model failing to look: AGENTS.md=yes, agent prompt=yes, RULES.md=no in the same reply.
  • Workaround that works: an explicit instruction in AGENTS.md telling the model to read the file ("read RULES.md in this folder before you start a task"). The model-side reading path is fine; only the config-driven injection is missing.
  • Observation, possibly intended: editing opencode.jsonc while the server runs has no effect on newly created sessions until opencode is restarted.

Activity

  1. github-actions commented on Sep 25, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of an existing issue. Please check:

    • #51262: Reports that V2's top-level config.instructions entries are never resolved into session context, the same behavior described here.
  2. vegerot commented on Sep 26, 2026

    @vegerot
    Contributor

    I can reproduce this on V2, and the impact is broader than a missing convenience: it breaks agent-specific configuration in multi-harness setups.

    My global behavioral instructions are intentionally shared among OpenCode, Codex, Claude Code, and Trae through their native global instruction files. I previously used OpenCode's top-level instructions array to add a separate OpenCode-only introspection rule. Moving that rule into the shared AGENTS.md would incorrectly expose OpenCode-specific guidance to every other harness.

    Source history confirms this is a missed V2 port rather than a new feature request. The legacy packages/opencode/src/session/instruction.ts implementation resolved config.instructions entries as local paths/globs (including ~/ and absolute paths) and HTTP(S) URLs. Native V2's ConfigInstructionPlugin currently discovers only global and ancestor AGENTS.md files, even though the schema retains instructions and the migration guide says it requires no migration. The legacy resolver disappeared when commit 44b6938b2ad2895bdd89d5d5cf753fb01ca8e3dd removed packages/opencode.

    I’m preparing a V2 fix with regression coverage for explicit instruction sources.

    Co-Authored-By: OpenCode v2

  3. lukastaegert commented on Oct 2, 2026

    @lukastaegert

    I have another use case that is currently broken by this gap: Adding project-specific instructions to a repository that already has AGENTS.md/CLAUDE.md instructions without checking them in.

    In some shared projects, I have some personal preferences that are specific to that repository but also do not make sense to share with others. While I could move the instructions up, that would either fill up the context in all other projects as well with useless instructions or otherwise if I just add a reference, it is not guaranteed that the instructions are always loaded.

    Would be nice to get this feature back.

  4. nkoynov commented on Oct 5, 2026

    @nkoynov

    +1, with our use case: we keep one global instructions file, ~/.claude/CLAUDE.md, and share it between Claude Code and OpenCode. If "instructions": ["~/.claude/CLAUDE.md"] worked, V2 could read that file as it is. Today we need a plugin to inject it, since V2 also dropped the CLAUDE.md fallback. PR #51422 would cover our case, because ~ paths are what we need.

  5. added 2 commits that reference this issue on Oct 6, 2026
    a276e6f
    8227111
  6. WhiteGiverMa commented on Oct 9, 2026

    @WhiteGiverMa

    Coming over from #54157 (closed as duplicate). I confirmed on tag v2.0.24 (Linux) that the field is wired through the schema and normalization but has no runtime consumer: packages/schema/src/config.ts:90 defines it, packages/core/src/config/normalize.ts:226-227 preserves it, and the session instruction pipeline (ConfigInstructionPlugin) only ever injects the global $CONFIG_DIR/AGENTS.md plus project-ancestor AGENTS.md files.

    My use case is the ~/ form: "instructions": ["~/.agents/AGENTS.md"] as one global file shared across machines. PR #51422 covers it (explicit ~/ expansion), so that would be my preferred fix.

    If the resolver approach is declined, please consider a config-load warning as the fallback. The migration guide notes unsupported leftovers like compaction.prune are ignored with a warning, but instructions currently validates and normalizes without a peep — the only way to discover the no-op is to notice your instructions never load. A one-line warning would have saved the debugging session on both sides.

  7. yg-codes commented on Oct 14, 2026

    @yg-codes

    Coming from #55345 (filed separately, then triaged as a duplicate of this issue). One data point that may help narrow this down: the same global config loads fine on the v1 line, so this is a v1 -> v2 regression rather than "never worked in v2".

    • v2.0.28: "instructions": ["/tmp/pluto-token.md"] (absolute path) in the global config + opencode run --standalone -> the model never sees the file; NONE when asked to echo a token defined only there
    • v1.19.0 (mise, identical file + config + prompt): injected correctly (token echoed)

    Full repro matrix in #55345, including: project-level opencode.json instructions equally inert (in-project relative and absolute paths); opencode debug config parses and displays the array in both the global and project docs (config resolution sees it, session injection ignores it); AGENTS.md discovery works in the same sessions -- global ~/.config/opencode/AGENTS.md plus the cwd-to-git-root chain, with per-level CLAUDE.md fallback and nothing above the git root.

    Subscribed here and to #51422 -- thanks for working the fix.

  8. added a commit that references this issue on Oct 14, 2026
    3e6f389
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions