Problem
The instructions array field inside an agent config block in opencode.jsonc does not resolve file paths into actual file content injected into the agent's system prompt.
Config Example
Expected Behavior
The contents of instructions.md should be composed into the agent's system prompt, same as how the top-level instructions field (outside agent blocks) behaves.
Actual Behavior
The V1->V2 config migration (packages/core/src/v1/config/migrate.ts -- migrateAgent()) puts info.options (which includes the instructions array via normalize() moving unknown keys to options) into request.body as opaque provider parameters. These are never resolved as file paths or injected into the system prompt.
Similarly, the V1 prompt field maps to V2 system via the migration, but the V2 runner populates agent.info.system from the agent definition file (the .md file with YAML frontmatter in ~/.config/opencode/agents/ or .opencode/agents/), not from the config file. This means:
- Config-level
prompt is silently overridden by the definition file
- Config-level
instructions goes to request.body and is never read
Workaround
Append supplementary instructions directly to the agent definition file (~/.config/opencode/agents/<name>.md). The body after the YAML frontmatter is the agent's system prompt.
Evidence
- The
InstructionContext system (packages/core/src/instruction-context.ts) only discovers AGENTS.md files by walking up from cwd -- it does not read the config's instructions field
- The V2
ConfigV2.Agent schema (packages/core/src/config/agent.ts) has system: Schema.String but no instructions field
- Testing confirms: setting
prompt: "TEST_STRING" in config with an existing definition file -- agent does NOT see the string. Appending content to the definition file body -- agent sees it immediately.
Environment
- OpenCode version: v1.17.x
- OS: Windows 11
Problem
The
instructionsarray field inside an agent config block inopencode.jsoncdoes not resolve file paths into actual file content injected into the agent's system prompt.Config Example
{ "agent": { "my-agent": { "instructions": ["path/to/instructions.md"] } } }Expected Behavior
The contents of
instructions.mdshould be composed into the agent's system prompt, same as how the top-levelinstructionsfield (outside agent blocks) behaves.Actual Behavior
The V1->V2 config migration (
packages/core/src/v1/config/migrate.ts--migrateAgent()) putsinfo.options(which includes theinstructionsarray vianormalize()moving unknown keys tooptions) intorequest.bodyas opaque provider parameters. These are never resolved as file paths or injected into the system prompt.Similarly, the V1
promptfield maps to V2systemvia the migration, but the V2 runner populatesagent.info.systemfrom the agent definition file (the.mdfile with YAML frontmatter in~/.config/opencode/agents/or.opencode/agents/), not from the config file. This means:promptis silently overridden by the definition fileinstructionsgoes torequest.bodyand is never readWorkaround
Append supplementary instructions directly to the agent definition file (
~/.config/opencode/agents/<name>.md). The body after the YAML frontmatter is the agent's system prompt.Evidence
InstructionContextsystem (packages/core/src/instruction-context.ts) only discoversAGENTS.mdfiles by walking up from cwd -- it does not read the config'sinstructionsfieldConfigV2.Agentschema (packages/core/src/config/agent.ts) hassystem: Schema.Stringbut noinstructionsfieldprompt: "TEST_STRING"in config with an existing definition file -- agent does NOT see the string. Appending content to the definition file body -- agent sees it immediately.Environment