Pattern 10. Complete Reference — Fields, Error Codes, Design Checklist
This document is a reference guide, not a tutorial. Refer to it whenever an error code occurs or you need to look up the meaning of a specific field.
1. Complete YAML Field Table
Top-Level Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id |
string | Required | -- | Unique identifier for the pattern. category.descriptor format recommended |
version |
integer | Required | -- | Schema version. Currently always 1 |
category |
string | Required | -- | Pattern category (free-form string: research, code, ops, writing, etc.) |
description |
string | Required | -- | Pattern description. Displayed in pattern list and pattern show |
defaults |
object | Optional | -- | Settings applied globally to all nodes |
nodes |
list | Required | -- | List of node definitions (excluding finalize) |
edges |
list | Required | -- | List of edge (transition condition) definitions |
finalize |
object | Required | -- | Final node configuration. Not included in the nodes array |
defaults Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
max_iterations |
integer | Required if cycles exist | -- | Maximum number of loops within a cycle. Forces finalize when exceeded |
max_total_tool_calls |
integer | Optional | Unlimited | Maximum total number of all tool calls across the entire execution |
max_web_search_calls |
integer | Optional | Unlimited | Maximum number of web.search calls across the entire execution |
pass_threshold |
float | Optional | 0.85 | Score threshold for Judge's finalize decision (runtime hint) |
dedupe_web_search |
boolean | Optional | false | When true, prevents duplicate execution of identical queries |
nodes Item Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id |
string | Required | -- | Unique node ID. finalize is a reserved word and cannot be used |
kind |
enum | Required | -- | llm or judge. finalize is declared as a top-level key |
runner |
object | Optional | -- | Execution mode settings |
runner.mode |
enum | Optional | execute |
execute (direct execution) or plan (execution after HITL approval) |
runner.force_tool |
string | Optional | -- | This tool must be used/proposed. Use with mode: plan |
runner.exclude_tools |
list | Optional | [] | List of tools prohibited for use in this node |
runner.min_proposals |
integer | Optional | -- | Minimum number of proposals in mode: plan |
runner.max_loops |
integer | Optional | -- | Maximum number of executions for this node |
prompt |
object | Optional | -- | Prompt configuration |
prompt.system_append |
string | Optional | -- | Text appended to the agent's default system prompt |
guardrails |
object | Optional | -- | Security/budget constraint settings |
guardrails.tool_call_budget |
object | Optional | -- | Per-node tool budget in {tool_name: max_count} format |
artifacts |
object | Optional | -- | Artifact settings |
artifacts.primary |
string | Optional | -- | Primary output filename for this node |
judge |
object | Required for kind=judge | -- | Settings exclusive to Judge nodes |
judge.schema |
string | Required | -- | Evaluation schema. Currently only evaluator_v1 is supported |
judge.route_values |
list | Required | -- | List of routing values the Judge can select |
edges Item Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
from |
string | Required | -- | Source node ID |
to |
string | Required | -- | Destination node ID. finalize is a reserved value |
when |
string | Required | -- | Transition condition. See the when DSL syntax reference |
finalize Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
artifact |
string | Required | -- | Artifact filename to save as the final output |
2. Complete when DSL Syntax Guide
The when field defines the transition condition of an edge.
Format 1: Always Transition
when: "true"
- Unconditionally transitions to the destination node as soon as the source node completes
- Do not use with nodes that have HITL pause (the pause would be immediately released)
- Most commonly used in linear flows
Format 2: After HITL Approval Completed
when: "approvals_resolved"
- Transitions when all HITL approval items from the source node have been processed
- Must be used on the edge following a node with
force_tool(mode: plan) - Rejected items are not executed, but the approval is considered resolved once all items are processed
Format 3: Judge Routing
when: "judge.route == finalize"
when: "judge.route == revise"
when: "judge.route == approve"
- Transitions when the routing result of the source node (judge type) matches the specified value
- Only values declared in
judge.route_valuescan be used - Case must match exactly (case-sensitive)
Format 4: Judge Score Comparison
when: "judge.score >= 0.85"
when: "judge.score < 0.70"
when: "judge.score >= 0.90"
- Transitions when the score of the source node (judge type) satisfies the condition
judge.routeandjudge.scorecannot be combined (only one per edge)- Range: 0.0 to 1.0
Invalid when Syntax
# 존재하지 않는 형식 — INVALID_WHEN_DSL
when: "judge.route == finalize AND judge.score > 0.8" # AND 조합 불가
when: "node_complete" # 알 수 없는 키워드
when: "score > 0.5" # 'judge.' 접두어 필요
when: "" # 빈 문자열 불가
when: true # boolean, string이어야 함
3. Complete Error Code Table
Stage 2 Error Codes (YAML Structural Validation)
| Code | Severity | Trigger Condition | Solution |
|---|---|---|---|
DUPLICATE_NODE_ID |
ERROR | The same id appears more than once in the nodes array |
Change the duplicate node ID to be unique |
RESERVED_NODE_ID |
ERROR | finalize is used as an ID in nodes |
Change the node ID to something like final_step; declare the final node using the top-level finalize: key |
EDGE_UNKNOWN_NODE |
ERROR | An edge's from or to references a non-existent node |
Check for typos. Ensure node IDs and edge references match exactly |
INVALID_WHEN_DSL |
ERROR | The when field is not in a supported DSL format |
See the when DSL syntax section. Only "true", "approvals_resolved", "judge.route == ...", "judge.score >= ..." formats are valid |
HITL_GATING_VIOLATION |
ERROR | force_tool is set but mode: execute is used |
Change to mode: plan |
JUDGE_SCHEMA_MISSING |
ERROR | A kind: judge node is missing judge.schema |
Add judge.schema: evaluator_v1 |
FORCE_EXCLUDE_CONFLICT |
ERROR | force_tool and exclude_tools specify the same tool |
Remove the overlapping tool from exclude_tools |
JUDGE_ROUTE_VALUES_MISSING |
ERROR | A kind: judge node is missing judge.route_values |
Add judge.route_values: [finalize, revise] |
DUPLICATE_ROUTE_VALUE |
ERROR | The same value appears more than once in route_values |
Remove the duplicate route_value |
JUDGE_ROUTE_COVERAGE_ERROR |
ERROR | A route_values entry has no corresponding edge |
Add an edge for the missing route_value |
Stage 3 Error Codes (IR Analysis)
| Code | Severity | Trigger Condition | Solution |
|---|---|---|---|
NO_ENTRY_NODE |
ERROR | All nodes have incoming edges, so there is no entry point | Remove all incoming edges connected to the first node |
MULTIPLE_ENTRY_NODES |
ERROR | Two or more nodes have no incoming edges | Add incoming edges to nodes that are not intended as entry points |
NO_FINALIZE |
ERROR | The top-level finalize: key is missing |
Add finalize: artifact: result.md |
UNBOUNDED_CYCLE |
ERROR | A cycle is detected but defaults.max_iterations is missing |
Add defaults.max_iterations: 3 |
FINALIZE_UNREACHABLE |
ERROR | Finalize cannot be reached through any path | Add edges connecting blocked paths to finalize |
BUDGET_INCONSISTENT |
ERROR | A node's tool_call_budget exceeds the global cap in defaults |
Reduce the node budget or increase the global cap |
JUDGE_DEAD_END |
ERROR | Following a specific Judge route cannot reach finalize | Add a path from that route to finalize |
FORCE_TOOL_NO_BUDGET |
ERROR | force_tool is set but the budget for that tool is 0 or unset with no default |
Add a budget for that tool in guardrails.tool_call_budget |
JUDGE_ROUTE_COVERAGE_ERROR |
ERROR | Also detected in Stage 2, but Stage 3 provides more accurate path analysis for additional detection | Add an edge for the missing route_value |
MISSING_JUDGE_ROUTE_EDGE |
WARNING | Declared in judge.route_values but no edge with when: "judge.route == ..." format exists (when other format when clauses exist) |
Use when: "judge.route == ..." format for Judge routing |
Note:
WARNINGpasses validation but indicates a potential issue.ERRORmeans validation failure, and pattern execution will be rejected.
4. Validation Stage Summary
Stage 1: JSON Schema Validation
What is validated:
- Presence of required fields (id, version, category, description, nodes, edges, finalize)
- Type validity (string/integer/boolean/list/object)
- Enum validity (kind: llm|judge, runner.mode: execute|plan)
- Whether version is a supported version
Related command: euleragent pattern validate <path> --format json -> stages.schema
Characteristics: The fastest stage. Only checks the structural validity of the YAML file itself.
Stage 2: YAML Structural Validation
What is validated: - Node ID uniqueness and reserved word conflicts - Whether edge from/to reference actual nodes - when DSL syntax validity - Existence of schema and route_values for Judge nodes - HITL gating rules (force_tool + mode combination) - Conflict between force_tool and exclude_tools
Related command: euleragent pattern validate <path> -> Stage 2 (Structural)
Characteristics: Checks internal consistency of the YAML. Graph topology is not yet analyzed.
Stage 3: IR Analysis Validation
What is validated: - Entry node uniqueness - Cycle detection and boundary verification - Reachability of finalize from all nodes - Judge route coverage and dead-ends - Budget consistency (node budget vs global cap) - Unreachable node detection (WARNING)
Related command: euleragent pattern compile <path> -> Generates IR JSON
Characteristics: The compiler performs graph analysis while converting YAML to IR. This is the most in-depth validation.
5. Pattern Design Checklist
Verify the following 20 items before writing and deploying a pattern.
Basic Structure
- [ ] 1. ID format: Does
idfollow thecategory.descriptorformat? Does it use only lowercase letters, dots, and underscores? - [ ] 2. Version: Is
version: 1declared? - [ ] 3. finalize declaration: Is the top-level
finalize:key present? (Not inside thenodesarray?) - [ ] 4. finalize artifact: Does
finalize.artifactmatch the last node'sartifacts.primary? - [ ] 5. Reserved word check: Is there no node with
id: finalize?
Node Design
- [ ] 6. Entry point uniqueness: Is there exactly one node with no incoming edges?
- [ ] 7. mode and force_tool combination: Does every node with
force_toolalso havemode: plan? - [ ] 8. exclude_tools consistency: For airgap patterns, do all nodes have
exclude_tools: [web.search, web.fetch]? - [ ] 9. max_loops setting: Do gate nodes (e.g., human_review) have
max_loops: 1? - [ ] 10. Judge schema: Do
kind: judgenodes havejudge.schema: evaluator_v1?
Judge Design
- [ ] 11. route_values declaration: Do
kind: judgenodes havejudge.route_values? - [ ] 12. route_values coverage: Does every
route_valuesentry have a correspondingwhen: "judge.route == ..."edge? - [ ] 13. No Judge dead-ends: Do all Judge route paths eventually reach
finalize? - [ ] 14. No duplicate route_values: Is every route_value declared only once?
Cycles and Boundaries
- [ ] 15. max_iterations setting: Is
defaults.max_iterationsdeclared when cycles exist? - [ ] 16. max_iterations sufficiency: When multiple cycles exist, is
max_iterationslarger than the total expected number of loops? - [ ] 17. No cycle intersection: Do the two cycles not share any nodes?
HITL and Budget
- [ ] 18. approvals_resolved usage: Does the edge following a
force_toolnode usewhen: "approvals_resolved"? (Notwhen: "true") - [ ] 19. Budget consistency: Is the node's
guardrails.tool_call_budgetvalue not greater thandefaults.max_web_search_calls? - [ ] 20. force_tool budget exists: Is a budget set for the tool specified by
force_tool?
Validation Commands
# 체크리스트 확인 후 최종 검증
euleragent pattern validate my_pattern.yaml
# JSON 형식으로 CI에서 활용
euleragent pattern validate my_pattern.yaml --format json | \
python3 -c "import json,sys; r=json.load(sys.stdin); exit(0 if r['overall']=='pass' else 1)"
# IR 분석 확인
euleragent pattern compile my_pattern.yaml
6. Common Pattern Archetypes
Here is a summary of frequently used pattern structures. Choose the appropriate archetype when designing a new pattern.
Archetype 1: Linear
[A] → [B] → [C] → finalize
- No cycles:
max_iterationsnot needed - No HITL: All edges use
when: "true" - Use cases: Simple pipelines, processing where each step is clearly delineated
- Reference tutorial: 03_simple_linear.md
defaults:
max_total_tool_calls: 10
edges:
- from: A; to: B; when: "true"
- from: B; to: C; when: "true"
- from: C; to: finalize; when: "true"
Archetype 2: Quality Loop
[draft] → [evaluate(judge)] → finalize
│
└──→ [revise] ──┐
└──→ [evaluate]
- Has cycles:
max_iterationsrequired - Judge routing:
route_values: [finalize, revise] - Use cases: Iterative improvement until quality criteria are met
- Reference tutorial: 04_judge_and_loop.md
defaults:
max_iterations: 3
pass_threshold: 0.85
judge:
route_values: [finalize, revise]
Archetype 3: Multi-Route
[evaluate(judge)] ──→ A → finalize
──→ B → C → evaluate (루프)
──→ finalize (즉시 종료)
- 3 or more route_values: All require edges
- Same destination possible: Multiple routes can go to
finalize - Use cases: Approve/request changes/reject, 3-level severity classification
- Reference tutorial: 07_multi_route.md
judge:
route_values: [approve, request_changes, reject]
Archetype 4: Human Gate
[draft] → [human_review(force_tool:file.write)] ──approvals_resolved──→ [evaluate]
- Forced HITL:
force_tool: file.write,mode: plan - Execute once only:
max_loops: 1 - Use cases: Legal/compliance documents, review before external publication
- Reference tutorial: 06_human_gate.md
runner:
mode: plan
force_tool: file.write
max_loops: 1
edges:
- from: human_review
to: next_node
when: "approvals_resolved"
Archetype 5: Airgap
모든 노드에 exclude_tools: [web.search, web.fetch]
- Complete external network blocking: Applied to all nodes
- Internal knowledge only: File reading and shell execution may be allowed
- Use cases: GDPR, internal confidential processing, security regulation compliance
- Reference tutorial: 08_airgap_and_ops.md
# 모든 노드에 반복
runner:
mode: execute
exclude_tools: [web.search, web.fetch]
Archetype 6: Dual Judge
[draft] → [judge_A] ──ok──→ [optimize] → [judge_B] ──ok──→ finalize
│ │
└──revise──→ [revise_A] ──┐ └──revise──→ [revise_B] ──┐
└──→ [judge_A] └──→ [judge_B]
- Two independent cycles: Must not intersect
- Independent route_values for each Judge: Different evaluation criteria
- Sufficient max_iterations: Consider the combined total of both cycles
- Use cases: Content + SEO, Functionality + Security, Translation + Proofreading
- Reference tutorial: 09_advanced_patterns.md
defaults:
max_iterations: 5 # 두 사이클 합산
nodes:
- id: judge_a
judge:
route_values: [ok_a, revise_a] # 독립적
- id: judge_b
judge:
route_values: [ok_b, revise_b] # 독립적
7. Quick Diagnostic Guide
How to quickly resolve issues when you receive an error code:
Detailed Inspection with JSON Output on Validation Failure
euleragent pattern validate my_pattern.yaml --format json
{
"stages": {
"schema": { "status": "pass", "errors": [] },
"structural": {
"status": "fail",
"errors": [
{
"code": "JUDGE_ROUTE_COVERAGE_ERROR",
"node": "evaluate",
"route_value": "revise",
"message": "No edge covers route_value 'revise'"
}
]
},
"ir_analysis": { "status": "skipped" }
}
}
Error Code -> Solution Quick Reference
DUPLICATE_NODE_ID → nodes의 id 중복 확인. grep -n "id:" pattern.yaml
RESERVED_NODE_ID → nodes에 id: finalize 있는지 확인
EDGE_UNKNOWN_NODE → 엣지 from/to와 nodes id 비교
INVALID_WHEN_DSL → when 값이 4가지 형식 중 하나인지 확인
NO_ENTRY_NODE → 수신 엣지 없는 노드가 있는지 그래프 그려서 확인
MULTIPLE_ENTRY_NODES → 수신 엣지 없는 노드가 2개 이상 → 하나 연결
NO_FINALIZE → 최상위 finalize: 키 추가
HITL_GATING_VIOLATION → force_tool 있는 노드에 mode: plan 추가
JUDGE_SCHEMA_MISSING → kind: judge 노드에 judge.schema: evaluator_v1 추가
FORCE_EXCLUDE_CONFLICT → force_tool과 exclude_tools 교집합 제거
JUDGE_ROUTE_VALUES_MISSING → kind: judge 노드에 judge.route_values 추가
DUPLICATE_ROUTE_VALUE → route_values 중 중복 제거
UNBOUNDED_CYCLE → defaults.max_iterations 추가
FINALIZE_UNREACHABLE → 막힌 경로에 finalize 연결 추가
BUDGET_INCONSISTENT → 노드 예산 ≤ 전역 캡 확인
JUDGE_DEAD_END → 해당 Judge 라우트 → finalize 경로 확인
FORCE_TOOL_NO_BUDGET → force_tool 도구의 guardrails.tool_call_budget 추가
JUDGE_ROUTE_COVERAGE_ERROR → 누락된 route_value에 엣지 추가
MISSING_JUDGE_ROUTE_EDGE → when: "judge.route == ..." 형식 엣지 확인
Runtime Error Diagnosis
# 실행 이벤트 확인
cat .euleragent/runs/<run-id>/pattern_events.jsonl
# 도구 호출 기록
cat .euleragent/runs/<run-id>/tool_calls.jsonl
# 승인 기록
cat .euleragent/runs/<run-id>/approvals.jsonl
# Judge 평가 결과만 추출
cat .euleragent/runs/<run-id>/pattern_events.jsonl | \
python3 -c "
import json, sys
for line in sys.stdin:
ev = json.loads(line)
if ev.get('event') == 'node.complete' and 'result' in ev:
r = ev['result']
if 'route' in r:
print(f\"{ev['node']}: score={r['score']}, route={r['route']}\")
"
8. Frequently Asked Questions
Q: Why is finalize not in the nodes array?
A: finalize is not a node but a "termination declaration" for the pattern. The runtime terminates the pattern whenever any node follows a to: finalize edge. Treating it as a regular node would complicate entry point calculation, cycle detection, and other analyses.
Q: Is it safe to set max_iterations to a very large value?
A: Technically possible, but not recommended. Large values can lead to unexpectedly high LLM call costs. Set it to approximately 1.5 to 2 times the actual number of loops needed.
Q: Can two nodes use the same artifact filename?
A: Yes. The later node overwrites the earlier node's file. A common pattern is for the revise node to overwrite the draft node's blog_post.md.
Q: Does dedupe_web_search set to true also block important re-searches?
A: Only identical query strings are detected as duplicates. Similar but different queries are not treated as duplicates. "LangChain tutorial" and "LangChain tutorial 2025" are considered different queries.
Q: Are there Judge schemas other than evaluator_v1?
A: Currently only evaluator_v1 is supported. Custom schemas are planned for future releases.
Q: What is the difference between running an agent without a pattern and with a pattern?
A: Without a pattern, the agent freely uses tools and generates results. With a pattern, the workflow is fixed, and HITL gating, budget constraints, and quality loops are guaranteed. Consider using patterns for complex and critical tasks, and pattern-free execution for simple and quick tasks.