Skip to content

${env.X} placeholders in agents.<name>.instruction silently pass through to the model #2614

@tdabasinskas

Description

@tdabasinskas

When a user writes ${env.SOME_VAR} inside an agent's instruction: field, docker-agent ships the literal placeholder text to the LLM as part of the system prompt without expansion, evaluation, or warning. The user has no signal that their template was not honored — the agent just behaves as if the placeholder were a literal string in the system prompt, which the model then tries to reason about.

Reproduction

agents:
  root:
    model: claude-sonnet-4-6
    description: Demo
    instruction: |
      You are an automated reviewer for ${env.TARGET_REPO}. Operate only on this repository.
    toolsets: []

Set TARGET_REPO=acme/foo in the runtime's environment. Run the agent. Inspect the system prompt agent sends to the model - it contains the literal text ${env.TARGET_REPO}, not acme/foo.

The same behavior applies to toolsets[*].instruction. Seems the overall behavior is quite inconsistent:

Field Expanded?
agents.<name>.description
agents.<name>.welcome_message
agents.<name>.commands
agents.<name>.instruction
toolsets[*].env
toolsets[*].instruction

I think the current approach (silently passing ${env.X} through to the model as content) - is the worst of the available options. Could we:

  1. Fail loud at agent load. Detect ${...} patterns in instruction: and toolsets[*].instruction: at load time and either error or log a WARN clearly identifying the offending field and pattern. This signals "you wrote what looks like a template literal in a field that doesn't support templating."

  2. Expand instruction: too. The current non-expansion is plausibly intentional - instruction: is typically multi-line user-authored prose that may contain literal ${...} for legitimate reasons (shell examples, regex snippets, the model's own format spec). Expanding by default would introduce a different footgun. Yet, being able to refer to environment variables in the prompt (even if it's somehow opt-in), would be quite useful.

Metadata

Metadata

Assignees

Labels

area/configFor configuration parsing, YAML, environment variableseffort:smallIsolated change, clear solution, single areapriority:highMajor impact, should be addressed within 2 days

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions