Compiler ErrorsAI Decisions & Prompts

AI Decisions & Prompts

Errors from the decisions: and prompts: blocks, and from op: decision call sites in rules.

19 error codes in this section.

AI Decisions

VERR_DECISION_SCHEMA_INVALID

Invalid input/output schema field. A field under a decision’s input: or output: map is neither a plain type string (subject: string) nor an object ({ type: string, required: true }).

Impact: Compilation aborts while parsing the decision — the field’s type can’t be determined.

✗ Won't compile
decisions:
  moderate_comment:
    input:
      comment_id: [string]   # not a valid shorthand or object form
✓ Fixed
decisions:
  moderate_comment:
    input:
      comment_id: string
      # or: { type: string, required: true }

VERR_DECISION_MISSING_EXECUTOR

Reserved — not currently emitted. This code is declared in CompilerErrorCode but is not currently thrown by any validator. The equivalent check — a decision declaring neither provider nor executor — reports VERR_DECISION_MISSING_PROVIDER instead.

Impact: None today. Documented here so the code isn’t a mystery if you see it referenced in compiler source.

✗ Won't compile
# No triggering condition today.
✓ Fixed
# See VERR_DECISION_MISSING_PROVIDER for the live version of this check.

VERR_DECISION_MISSING_PROMPT

Decision missing prompt reference. A decisions: entry has no prompt field — the compiler doesn’t know which prompts: entry supplies the instructions for this decision’s LLM call.

Impact: Compilation aborts; the decision has no instructions to send to the model.

✗ Won't compile
decisions:
  moderate_comment:
    provider: reasoning
    # prompt missing
✓ Fixed
decisions:
  moderate_comment:
    provider: reasoning
    prompt: moderation_prompt

VERR_DECISION_PROMPT_NOT_FOUND

Decision references unknown prompt. A decision’s prompt value doesn’t match any key under the top-level prompts: block.

Impact: Compilation aborts — the decision points to a prompt that doesn’t exist.

✗ Won't compile
decisions:
  moderate_comment:
    prompt: moderaton_prompt   # typo — not declared under prompts:
✓ Fixed
decisions:
  moderate_comment:
    prompt: moderation_prompt   # matches prompts.moderation_prompt

VERR_DECISION_MISSING_EMITS

Decision missing emits event. A decisions: entry has no emits field — the compiler doesn’t know which event to emit with the decision’s output once the LLM call completes.

Impact: Compilation aborts; the decision’s result has nowhere to go.

✗ Won't compile
decisions:
  moderate_comment:
    prompt: moderation_prompt
    # emits missing
✓ Fixed
decisions:
  moderate_comment:
    prompt: moderation_prompt
    emits: CommentModerated

VERR_DECISION_EMITS_NOT_FOUND

Decision emits unknown event. A decision’s emits value doesn’t match any key under the top-level events: block.

Impact: Compilation aborts — the decision would emit an event the rest of the app has never declared.

✗ Won't compile
decisions:
  moderate_comment:
    emits: CommentModerate   # typo — not declared under events:
✓ Fixed
decisions:
  moderate_comment:
    emits: CommentModerated   # matches events.CommentModerated

VERR_DECISION_MISSING_INPUT

Decision missing input schema. A decisions: entry has no input: map, or it’s empty — the compiler needs to know what data feeds the prompt template and the op: decision call site.

Impact: Compilation aborts; there’s no schema to validate op: decision input against.

✗ Won't compile
decisions:
  moderate_comment:
    prompt: moderation_prompt
    # input missing
✓ Fixed
decisions:
  moderate_comment:
    prompt: moderation_prompt
    input:
      comment: string

VERR_DECISION_MISSING_OUTPUT

Decision missing output schema. A decisions: entry has no output: map, or it’s empty — the compiler needs a schema for the structured result the LLM must return.

Impact: Compilation aborts; the model’s response has no declared shape to validate or map onto the emitted event.

✗ Won't compile
decisions:
  moderate_comment:
    input:
      comment: string
    # output missing
✓ Fixed
decisions:
  moderate_comment:
    input:
      comment: string
    output:
      flagged: boolean
      reason: string

VERR_DECISION_MEMORY_NOT_FOUND

Decision references unknown memory. A decision’s memories: list includes a name that doesn’t match any key under the top-level memories: block.

Impact: Compilation aborts — the decision’s prompt can’t retrieve context from a memory that doesn’t exist.

✗ Won't compile
decisions:
  moderate_comment:
    memories: [customer_memry]   # typo — not declared under memories:
✓ Fixed
decisions:
  moderate_comment:
    memories: [customer_memory]   # matches memories.customer_memory

VERR_DECISION_EVENT_CONTRACT

Decision schema doesn’t satisfy emitted event. The union of a decision’s input and output fields is missing a field the emitted event’s payload requires, or provides one with an incompatible type. (Fields derived from the rule’s entity_expr are excluded from this check.)

Impact: Compilation aborts — the emitted event’s payload can’t be fully populated from the decision’s declared fields.

✗ Won't compile
events:
  CommentModerated:
    payload:
      flagged: boolean
      reason: string
decisions:
  moderate_comment:
    emits: CommentModerated
    output:
      flagged: boolean
      # 'reason' missing from input+output
✓ Fixed
decisions:
  moderate_comment:
    emits: CommentModerated
    output:
      flagged: boolean
      reason: string   # now satisfies the event payload

VERR_DECISION_OP_MISSING_REF

op: decision missing ref. An op: decision entry in a rule has no ref field — the compiler doesn’t know which decisions: entry to invoke.

Impact: Compilation aborts for this rule; the AI call has nothing to execute.

✗ Won't compile
then:
  - op: decision
    input:
      comment: intent.comment
✓ Fixed
then:
  - op: decision
    ref: moderate_comment
    input:
      comment: intent.comment

VERR_DECISION_OP_REF_NOT_FOUND

op: decision references unknown decision. An op: decision’s ref value doesn’t match any key under the top-level decisions: block.

Impact: Compilation aborts — the rule calls a decision that was never declared.

✗ Won't compile
then:
  - op: decision
    ref: moderate_commment   # typo — not declared under decisions:
✓ Fixed
then:
  - op: decision
    ref: moderate_comment   # matches decisions.moderate_comment

VERR_DECISION_OP_MISSING_INPUT

op: decision missing required input. A field declared as required in the decision’s input: schema is absent from the op’s own input: map.

Impact: Compilation aborts — the decision would run without a value it needs.

✗ Won't compile
decisions:
  moderate_comment:
    input:
      comment: { type: string, required: true }
      author_id: { type: string, required: true }
then:
  - op: decision
    ref: moderate_comment
    input:
      comment: intent.comment
      # author_id missing
✓ Fixed
then:
  - op: decision
    ref: moderate_comment
    input:
      comment: intent.comment
      author_id: intent.author_id

VERR_DECISION_OP_UNKNOWN_INPUT

op: decision has unknown input. The op’s input: map supplies a key that doesn’t exist in the decision’s declared input: schema.

Impact: Compilation aborts — the extra field can never reach the prompt template or the model call.

✗ Won't compile
then:
  - op: decision
    ref: moderate_comment
    input:
      comment: intent.comment
      extra_field: intent.something   # not in decision's input schema
✓ Fixed
then:
  - op: decision
    ref: moderate_comment
    input:
      comment: intent.comment

VERR_DECISION_OP_INPUT_TYPE_MISMATCH

op: decision input type mismatch. A literal value passed in op: decision’s input: doesn’t match the type declared in the decision’s input schema. Expressions (e.g. intent.amount) skip this check — only static literals are type-checked at compile time.

Impact: Compilation aborts — the literal would fail validation (or silently coerce) at runtime.

✗ Won't compile
decisions:
  score_risk:
    input:
      amount: { type: number, required: true }
then:
  - op: decision
    ref: score_risk
    input:
      amount: "not-a-number"   # literal string against a number field
✓ Fixed
then:
  - op: decision
    ref: score_risk
    input:
      amount: intent.amount   # expression, or a literal number: 42.0

VERR_DECISION_MISSING_PROVIDER

Decision missing provider or executor. A decisions: entry declares neither provider (references a providers: entry) nor the legacy direct executor field.

Impact: Compilation aborts; the decision has no model backend to call.

✗ Won't compile
decisions:
  moderate_comment:
    prompt: moderation_prompt
    # neither provider nor executor set
✓ Fixed
decisions:
  moderate_comment:
    prompt: moderation_prompt
    provider: reasoning   # references providers.reasoning

VERR_DECISION_NOT_SIDE_EFFECT

op: decision must run in side_effects. An op: decision appears in a preflight or core rule block. AI calls are external and non-deterministic, so they’re only allowed in side_effects, which aren’t replayed.

Impact: Compilation aborts — allowing this in core/preflight would break deterministic replay.

✗ Won't compile
core:
  rules:
    - name: moderate
      then:
        - op: decision
          ref: moderate_comment
✓ Fixed
side_effects:
  rules:
    - name: moderate
      then:
        - op: decision
          ref: moderate_comment

AI Prompts

VERR_PROMPT_MISSING_INSTRUCTIONS

Prompt missing instructions. A prompts: entry has no instructions field — there’s no template text to send to the model.

Impact: Compilation aborts; any decision referencing this prompt has nothing to send the LLM.

✗ Won't compile
prompts:
  moderation_prompt: {}
✓ Fixed
prompts:
  moderation_prompt:
    instructions: |
      Review this comment for policy violations: {{ comment }}

VERR_PROMPT_UNKNOWN_VARIABLE

Prompt references unknown variable. A {{ variable }} placeholder in a prompt’s instructions isn’t one of the linked decision’s input fields or one of its memories.<name> references. This is checked on the decision → prompt link, not when the prompt is defined standalone.

Impact: Compilation aborts — the placeholder could never be filled in at runtime.

✗ Won't compile
decisions:
  moderate_comment:
    prompt: moderation_prompt
    input:
      comment: string
prompts:
  moderation_prompt:
    instructions: "Review: {{ commment }}"   # typo, not in decision.input
✓ Fixed
prompts:
  moderation_prompt:
    instructions: "Review: {{ comment }}"   # matches decision.input.comment