Skip to content

feat(validation): warn when explicit-mode agent prompts reference undeclared inputs #105

@PolyphonyRequiem

Description

@PolyphonyRequiem

Provenance: AI-drafted (GitHub Copilot CLI / Claude Opus 4.6), human-reviewed and approved, AI-submitted.

Problem

When using context.mode: explicit, agent prompts can reference {{ workflow.input.X }} variables that aren't declared in the agent's input: list. The workflow validates and loads successfully, but fails at runtime with a TemplateError:

TemplateError: Undefined variable in template: 'dict object' has no attribute 'prompt'

This is a silent misconfiguration — the validator doesn't check whether prompt templates reference variables that will be available in the agent's scoped context.

Example

workflow:
  name: example
  context:
    mode: explicit
  input:
    work_item_id: { type: number, required: true }
    prompt: { type: string, required: false }

agents:
  - name: intake
    input:
      - workflow.input.work_item_id   # declared
      # workflow.input.prompt NOT declared
    prompt: |
      Work item: {{ workflow.input.work_item_id }}
      {% if workflow.input.prompt %}          <-- BOOM: 'prompt' not in scope
      Prompt: {{ workflow.input.prompt }}
      {% endif %}

conductor validate reports success. At runtime, the prompt template fails because workflow.input.prompt isn't in the agent's explicit context.

Impact

This is especially painful when:

  • Sharing prompts across workflows via !file — different workflows declare different inputs, but the shared prompt references all of them
  • Extracting sub-workflows — the new workflow needs to re-declare every input the shared prompt touches, and missing one is a silent error until runtime
  • Refactoring inputs — adding/renaming a workflow input requires checking every agent's input: list manually

We hit this repeatedly while decomposing a large workflow into sub-workflows. Each missing input declaration caused a runtime crash that could have been caught at validation time.

Proposed solution

During conductor validate, when context.mode: explicit:

  1. Parse Jinja2 template expressions in each agent's prompt and system_prompt
  2. Extract referenced variables (e.g., workflow.input.X, agent_name.output.Y)
  3. Check that each referenced variable is reachable from the agent's input: declarations
  4. Emit a warning (not error) for unreachable references — some may be guarded by {% if X is defined %} conditionals

A warning is preferable to an error because:

  • Some templates use {% if X is defined %} guards intentionally
  • Full Jinja2 static analysis is hard; false positives are possible
  • A warning catches the common case (forgot to add to input:) without breaking valid workflows

Scope

This applies to explicit mode only. In accumulate and last_only modes, all prior outputs are available, so missing input: declarations don't cause template failures.

Provenance: Found during production workflow decomposition. AI-reported, human-reviewed.

Metadata

Metadata

Assignees

No one assigned

    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