Diagnostic codes

Every diagnostic emitted by harn check, harn lint, and harn fmt carries a stable HARN-<CAT>-<NNN> code. Codes are dispatchable: agents, IDEs, and the hosted error pages all read the same apiStability: stable contract, so cross-tooling integrations never have to regex on prose.

Look up a single code interactively:

harn explain HARN-TYP-014
harn explain HARN-TYP-014 --json

The structured JSON sidecar that drives this page is committed at docs/diagnostics-catalog.json — its schemaVersion: 1 shape is the contract consumed by downstream tooling (burin-code's IDE diagnostic panel, harn-cloud's hosted error pages). Regenerate locally with make sync-diagnostics-catalog.

Prose-style tour of common shape and nilable diagnostics: Reading shape diagnostics.

Repair safety classes

Repairs are tagged with a six-level safety class so harn fix --apply --safety <ceiling> and IDE auto-apply policies can dispatch without inspecting individual edits:

ClassMeaning
format-onlyWhitespace, trivia, or canonical layout only. Always safe to auto-apply.
behavior-preservingIntended not to change observable runtime behavior.
scope-localConfined to the current local scope or file; blast radius does not cross a public surface.
surface-changingTouches a signature, export, or call-site surface other files can observe.
capability-changingRequired capabilities or sandbox profile may change.
needs-humanPlanning hint only — propose, never auto-apply.

Categories

CategoryTitleCodes
TYPType checker25
PARParser / lexer6
NAMNaming and resolution13
CAPCapabilities9
LLMLLM calls5
ORCOrchestration constructs12
STDStdlib usage4
PRMPrompt templates7
MODModules and exports6
RMDReminder lifecycle8
SUSSuspend / resume lifecycle13
LNTLint rules59
FMTFormatter3
IMPImport resolution3
OWNOwnership and mutability4
RCVError recovery3
MATMatch exhaustiveness3
POLRuntime policies2
METCompile-time meta restrictions1
CSTConst-eval sandbox4
CMPBytecode compilation1

TYP — Type checker

Harn's static type checker rejects programs whose types do not unify. Type errors block compilation — Harn refuses to run a program until they are fixed.

CodeSummaryRepairSafety
HARN-TYP-001expected and actual types are incompatiblecasts/insert-explicit-conversionscope-local
HARN-TYP-002binary operator is not defined for the operand types
HARN-TYP-003string concatenation should be rewritten as interpolationstyle/string-interpolationbehavior-preserving
HARN-TYP-004returned expression does not match the declared return typecasts/insert-explicit-conversionscope-local
HARN-TYP-005assigned value does not match the target typecasts/insert-explicit-conversionscope-local
HARN-TYP-006argument value does not match the parameter typecasts/insert-explicit-conversionscope-local
HARN-TYP-007initializer does not match the declared variable typecasts/insert-explicit-conversionscope-local
HARN-TYP-008closure return expression does not match its declared typecasts/insert-explicit-conversionscope-local
HARN-TYP-009field value does not match its declared typecasts/insert-explicit-conversionscope-local
HARN-TYP-010method receiver or result type is incompatiblecasts/insert-explicit-conversionscope-local
HARN-TYP-011callable does not accept type arguments
HARN-TYP-012type argument does not satisfy the generic parameter
HARN-TYP-013generic call has the wrong number of type arguments
HARN-TYP-014declaration has the wrong number of type parameters
HARN-TYP-015type argument does not satisfy a where-clause constraint
HARN-TYP-016expression must be iterable
HARN-TYP-017subscript index type is invalidcasts/insert-explicit-conversionscope-local
HARN-TYP-018expression must be callable
HARN-TYP-019cast cannot be proven validcasts/remove-uncheckedscope-local
HARN-TYP-020type name cannot be resolvedimports/fix-pathscope-local
HARN-TYP-021variant type is used in an invalid position
HARN-TYP-022struct literal is invalid
HARN-TYP-023enum construction is invalid
HARN-TYP-024pattern binding is invalid for the expected type
HARN-TYP-025optional access is invalid for the receiver type

PAR — Parser / lexer

The lexer or parser raises these before type checking begins. Harn cannot build an AST from the source until the offending token sequence is repaired.

CodeSummaryRepairSafety
HARN-PAR-001parser found an unexpected token
HARN-PAR-002parser reached end of file while expecting syntax
HARN-PAR-003lexer found an unexpected character
HARN-PAR-004string literal is unterminated
HARN-PAR-005block comment is unterminated
HARN-PAR-006integer literal is out of range for int (i64)

NAM — Naming and resolution

Name resolution failed: the identifier, field, or attribute referenced does not match anything in the visible scope. Harn cannot proceed without a binding.

CodeSummaryRepairSafety
HARN-NAM-001variable name cannot be resolvedbindings/rename-to-closestscope-local
HARN-NAM-002function name cannot be resolvedbindings/rename-to-closestscope-local
HARN-NAM-003attribute name is not recognized
HARN-NAM-004field name does not exist on the target typebindings/rename-to-closestscope-local
HARN-NAM-005method name does not exist on the receiver typebindings/rename-to-closestscope-local
HARN-NAM-006argument name is duplicated
HARN-NAM-007option key is not recognized
HARN-NAM-008builtin name cannot be resolvedbindings/rename-to-closestscope-local
HARN-NAM-009function call targets a deprecated declarationstdlib/migrate-renamedscope-local
HARN-NAM-010declaration reference cannot be resolvedbindings/rename-to-closestscope-local
HARN-NAM-011attribute is attached to an unsupported declaration
HARN-NAM-012attribute argument is invalid
HARN-NAM-101main entrypoint must take a single harness: Harness parameterbindings/thread-harness-needs-paramsurface-changing

CAP — Capabilities

A host capability call (file I/O, network, HITL approval, tool host, etc.) failed static validation. Capabilities are the trust boundary between Harn scripts and the embedding host, so checks are strict by design.

CodeSummaryRepairSafety
HARN-CAP-001capability payload is invalid
HARN-CAP-002human approval construct is missing policy
HARN-CAP-003human approval argument is invalid
HARN-CAP-004capability result must be checkederrors/check-or-rescuescope-local
HARN-CAP-005host capability operation is not declared
HARN-CAP-006host capability call must use a static operation name
HARN-CAP-007tool host capability binding is invalidmanual/review-capability-bindingneeds-human
HARN-CAP-201harness capability denied by active sandbox profile
HARN-CAP-301child agent effect set exceeds the parent's declared effectspolicy/narrow-child-effectssurface-changing

LLM — LLM calls

An llm_call(...) invocation violates the schema Harn enforces. Schema-validated, provider-portable LLM calls are a load-bearing Harn contract; drift in the options table is rejected at check time.

CodeSummaryRepairSafety
HARN-LLM-001LLM option key is not recognized
HARN-LLM-002LLM option key is deprecatedllm/migrate-deprecated-optionscope-local
HARN-LLM-003LLM call is missing schema validationllm/add-schemasurface-changing
HARN-LLM-004LLM schema option is invalid
HARN-LLM-005prompt branches on provider identity instead of capability flagsllm/use-capability-flagcapability-changing

ORC — Orchestration constructs

An orchestration construct — agent / workflow / pipeline / tool definition, or a call to an orchestration builtin — is shaped in a way the orchestrator cannot accept.

CodeSummaryRepairSafety
HARN-ORC-001orchestration construct has invalid arity
HARN-ORC-002orchestration construct argument has invalid type
HARN-ORC-003agent declaration is invalid
HARN-ORC-004workflow declaration is invalid
HARN-ORC-005tool declaration is invalid
HARN-ORC-006pipeline declaration is invalid
HARN-ORC-007select construct is invalid
HARN-ORC-008statement cannot be reachedcontrol-flow/remove-deadbehavior-preserving
HARN-ORC-009Flow invariant attribute set is invalid
HARN-ORC-010execution target path cannot be found
HARN-ORC-011a self-deadlock acquire would block forever
HARN-ORC-012a wait-for graph cycle would block forever

STD — Stdlib usage

A stdlib symbol is used in a way Harn does not support, or has been renamed/removed and the call site still references the old surface.

CodeSummaryRepairSafety
HARN-STD-001stdlib symbol has been renamed or deprecatedstdlib/migrate-renamedscope-local
HARN-STD-002stdlib call is invalid
HARN-STD-003builtin call has invalid arity
HARN-STD-101public stdlib function is missing declared metadatadoc/add-stdlib-metadatabehavior-preserving

PRM — Prompt templates

A prompt template (.harn.prompt / .prompt) failed validation, either because its front matter is missing required fields or because the body references slots the schema does not declare.

CodeSummaryRepairSafety
HARN-PRM-001prompt template cannot be parsed
HARN-PRM-002prompt template has too many capability-aware branchesmanual/needs-humanneeds-human
HARN-PRM-003prompt construction risks direct injectionprompts/escape-injectionscope-local
HARN-PRM-004prompt template branches on provider identityllm/use-capability-flagcapability-changing
HARN-PRM-005prompt references a tool outside the declared surfaceprompts/add-tool-to-surfacesurface-changing
HARN-PRM-006prompt references a deferred tool without tool searchprompts/add-tool-to-surfacesurface-changing
HARN-PRM-007prompt or template target cannot be found

MOD — Modules and exports

A module-level import declaration cannot be satisfied or has been authored in a shape Harn rejects. Module boundaries are checked before the body is type-checked.

CodeSummaryRepairSafety
HARN-MOD-001module import cannot be resolvedimports/fix-pathscope-local
HARN-MOD-002module import is unusedimports/remove-unusedbehavior-preserving
HARN-MOD-003module imports are not in canonical orderimports/reorderformat-only
HARN-MOD-004module export is invalid
HARN-MOD-005module imports expose colliding names
HARN-MOD-006module re-exports conflict

RMD — Reminder lifecycle

Reminder lifecycle errors are raised by session/remind and friends when the payload, tags, or scheduling do not match the documented contract.

CodeSummaryRepairSafety
HARN-RMD-001reminder lifecycle option key is not recognized
HARN-RMD-002reminder payload shape is invalid
HARN-RMD-003user_block reminder role hint is not supported by the selected provider
HARN-RMD-004discardable reminder has no TTL
HARN-RMD-005reminder propagate value is not recognized
HARN-RMD-006reminder provider returned a malformed reminder spec
HARN-RMD-007too many reminder providers are enabled
HARN-RMD-008hook event does not support reminder effects

SUS — Suspend / resume lifecycle

Suspend / resume lifecycle errors are raised when a worker is suspended, resumed, or queried outside the lifecycle states the operation supports.

CodeSummaryRepairSafety
HARN-SUS-001suspend_agent target worker is not running
HARN-SUS-002ResumeConditions validation failed
HARN-SUS-003resume_agent target worker is not suspended
HARN-SUS-004resume snapshot cannot be loaded or used
HARN-SUS-005agent_await_resumption was invoked outside agent_loop structural handling
HARN-SUS-006concurrent resume changed the worker before resume could complete
HARN-SUS-007ResumeConditions trigger could not be registered
HARN-SUS-008resume timeout action is unsupported
HARN-SUS-009resume input failed agent_loop input validation
HARN-SUS-010closed suspended worker cannot be resumed
HARN-SUS-011replay resume input hash diverges from journaled suspension
HARN-SUS-012replay drain decision prompt hash diverges from journaled receipt
HARN-SUS-013lifecycle receipt signed timestamp failed verification

LNT — Lint rules

Lints are not hard errors. The code compiles, but Harn flags the pattern as likely-incorrect, unidiomatic, or risky in a production agent. Most lints can be auto-fixed.

CodeSummaryRepairSafety
HARN-LNT-001renamed stdlib symbol lintstdlib/migrate-renamedscope-local
HARN-LNT-002cyclomatic complexity lint
HARN-LNT-003naming convention lintstyle/rename-to-conventionsurface-changing
HARN-LNT-004eager collection conversion lintcollections/prefer-lazyscope-local
HARN-LNT-005redundant clone lintclones/remove-redundantbehavior-preserving
HARN-LNT-006long-running workflow cleanup lintmanual/needs-humanneeds-human
HARN-LNT-007MCP tool annotations lintmanual/needs-humanneeds-human
HARN-LNT-008PR open without secret scan lint
HARN-LNT-009shadow variable lintbindings/rename-shadowscope-local
HARN-LNT-010persona hook target lint
HARN-LNT-011dead code after return lintcontrol-flow/remove-deadbehavior-preserving
HARN-LNT-012let then return lintcontrol-flow/flattenbehavior-preserving
HARN-LNT-013unhandled approval result linterrors/check-or-rescuescope-local
HARN-LNT-014unused variable lintbindings/rename-unusedbehavior-preserving
HARN-LNT-015unused pattern binding lintbindings/rename-unusedbehavior-preserving
HARN-LNT-016unused parameter lintbindings/rename-unusedbehavior-preserving
HARN-LNT-017unused import lintimports/remove-unusedbehavior-preserving
HARN-LNT-018mutable never reassigned lintbindings/make-immutablebehavior-preserving
HARN-LNT-019unused function lintdeclarations/remove-unusedsurface-changing
HARN-LNT-020unused type lintdeclarations/remove-unusedsurface-changing
HARN-LNT-021persona body must call steps lint
HARN-LNT-022undefined function lint
HARN-LNT-023pipeline return type lint
HARN-LNT-024missing harndoc lintdoc/add-harndocbehavior-preserving
HARN-LNT-025assert outside test lint
HARN-LNT-026prompt injection risk lintprompts/escape-injectionscope-local
HARN-LNT-027connector effect policy lint
HARN-LNT-028unnecessary cast lintcasts/remove-redundantbehavior-preserving
HARN-LNT-029untyped dict access linttypes/add-shape-annotationsurface-changing
HARN-LNT-030constant logical operand lintexpressions/simplifybehavior-preserving
HARN-LNT-031pointless comparison lintexpressions/simplifybehavior-preserving
HARN-LNT-032comparison to bool lintexpressions/simplifybehavior-preserving
HARN-LNT-033invalid binary operator literal lint
HARN-LNT-034redundant nil ternary lintexpressions/simplifybehavior-preserving
HARN-LNT-035empty block lintblocks/remove-emptyscope-local
HARN-LNT-036unnecessary else return lintcontrol-flow/flattenbehavior-preserving
HARN-LNT-037duplicate match arm lintmatch/remove-duplicate-armbehavior-preserving
HARN-LNT-038require in test lint
HARN-LNT-039break outside loop lint
HARN-LNT-040template parse lint
HARN-LNT-041blank line between items lintformat/reformatformat-only
HARN-LNT-042trailing comma lintformat/reformatformat-only
HARN-LNT-043unnecessary parentheses lintformat/reformatformat-only
HARN-LNT-044template variant explosion lintmanual/needs-humanneeds-human
HARN-LNT-045require file header lintformat/reformatformat-only
HARN-LNT-046template provider identity branch lintllm/use-capability-flagcapability-changing
HARN-LNT-047import order lintimports/reorderformat-only
HARN-LNT-048prefer optional shorthand lintexpressions/simplifybehavior-preserving
HARN-LNT-049legacy doc comment lintdoc/migrate-comment-styleformat-only
HARN-LNT-050deprecated LLM options lintllm/migrate-deprecated-optionscope-local
HARN-LNT-051unnecessary safe navigation lintexpressions/simplifybehavior-preserving
HARN-LNT-052ambient clock builtin replaced by harness.clock.*bindings/thread-harness-clockscope-local
HARN-LNT-053ambient stdio builtin replaced by harness.stdio.*bindings/thread-harnessscope-local
HARN-LNT-054ambient fs builtin replaced by harness.fs.*bindings/thread-harness-fsscope-local
HARN-LNT-055ambient env builtin replaced by harness.env.*bindings/thread-harness-envscope-local
HARN-LNT-056ambient random builtin replaced by harness.random.*bindings/thread-harness-randomscope-local
HARN-LNT-057ambient net builtin replaced by harness.net.*bindings/thread-harness-netscope-local
HARN-LNT-058if / while / guard condition is statically known to always succeed or always fail
HARN-LNT-059project rule-engine or native lint rule

FMT — Formatter

The formatter could not produce a canonical layout — either the input contains a construct it does not know how to render, or a layout rule was violated in a way auto-fix cannot resolve.

CodeSummaryRepairSafety
HARN-FMT-001formatter could not parse the source
HARN-FMT-002source is not in canonical formatformat/reformatformat-only
HARN-FMT-003formatter normalized trailing comma layoutformat/reformatformat-only

IMP — Import resolution

Import resolution failed at a deeper layer than MOD — the file, symbol, or package referenced in an import declaration could not be located, parsed, or exposed.

CodeSummaryRepairSafety
HARN-IMP-001import target cannot be resolvedimports/fix-pathscope-local
HARN-IMP-002imported symbol does not exist
HARN-IMP-003import graph contains a cycle

OWN — Ownership and mutability

Harn's binding-and-mutability discipline rejects this usage. let bindings may not be reassigned; mut bindings should actually be reassigned somewhere.

CodeSummaryRepairSafety
HARN-OWN-001immutable binding is reassignedbindings/make-mutablescope-local
HARN-OWN-002mutable binding is never reassignedbindings/make-immutablebehavior-preserving
HARN-OWN-003owned value escapes its valid scope
HARN-OWN-004unvalidated boundary value is used directly

RCV — Error recovery

A recovery construct (try, rescue) is in an invalid position or shaped in a way Harn's error-recovery rules cannot accept.

CodeSummaryRepairSafety
HARN-RCV-001rescue construct is outside a function bodyerrors/wrap-in-fnsurface-changing
HARN-RCV-002try construct is outside a function bodyerrors/wrap-in-fnsurface-changing
HARN-RCV-003rescue construct is invalid

MAT — Match exhaustiveness

A match expression is incomplete, ambiguous, or otherwise invalid. Harn requires arms to cover every variant of the scrutinee type — partial matches must opt in with an explicit catch-all.

CodeSummaryRepairSafety
HARN-MAT-001match expression is not exhaustivematch/add-missing-armsscope-local
HARN-MAT-002match expression contains a duplicate armmatch/remove-duplicate-armbehavior-preserving
HARN-MAT-003match pattern is invalid

POL — Runtime policies

A runtime policy (pool backpressure, scheduling, quotas) rejected the attempt. Policies are configurable, but defaults are tuned for safety over throughput.

CodeSummaryRepairSafety
HARN-POL-001pool backpressure rejected a submit
HARN-POL-002fail-fast pool has no immediate capacity

MET — Compile-time meta restrictions

A const binding's right-hand side must be a pure expression evaluable at compile time under the const-eval sandbox. These codes flag constructs the sandbox rejects.

CodeSummaryRepairSafety
HARN-MET-001expression is not permitted in a const initializer

CST — Const-eval sandbox

The bounded const-eval sandbox enforces step, recursion, and capability limits on every const initializer so a hostile or accidental expression cannot stall the compiler.

CodeSummaryRepairSafety
HARN-CST-001const initializer exceeded the step budget
HARN-CST-002const initializer exceeded the recursion depth budget
HARN-CST-003const initializer attempted a sandboxed capability
HARN-CST-004const initializer raised a runtime error during evaluation

CMP — Bytecode compilation

The bytecode compiler rejected a program that parsed and type-checked. These are structural / codegen errors the type checker does not model — harn check runs the compile pass too, so anything that would stop harn run is reported up front.

CodeSummaryRepairSafety
HARN-CMP-001the program failed to compile to bytecode

Code reference

HARN-TYP-001

Category: TYP (Type checker)  ·  API stability: stable

expected and actual types are incompatible

What it means

Harn's type checker compared the inferred ("actual") type of an expression against the type the surrounding context expects, and the two did not unify. This is the most common type error — it covers any mismatch that doesn't fall into one of the more specific TYP codes (assignment, argument, return, etc.).

How to fix

  • Adjust the expression so its inferred type matches the surrounding context.
  • Widen the declared type at the binding / parameter / return position to accept the actual type.
  • Convert the value explicitly (as, a stdlib coercion, etc.) when a safe conversion exists.
  • If the mismatch is between a concrete type and an optional, use ?-chaining or supply a default with ??.

HARN-TYP-002

Category: TYP (Type checker)  ·  API stability: stable

binary operator is not defined for the operand types

HARN-TYP-003

Category: TYP (Type checker)  ·  API stability: stable

string concatenation should be rewritten as interpolation

  • Repair: style/string-interpolation  ·  Safety: behavior-preserving
  • Rewrite string concatenation as an interpolation literal

HARN-TYP-004

Category: TYP (Type checker)  ·  API stability: stable

returned expression does not match the declared return type

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type
  • See also: HARN-TYP-001, HARN-TYP-008

HARN-TYP-005

Category: TYP (Type checker)  ·  API stability: stable

assigned value does not match the target type

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type
  • See also: HARN-TYP-001, HARN-TYP-007

HARN-TYP-006

Category: TYP (Type checker)  ·  API stability: stable

argument value does not match the parameter type

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type
  • See also: HARN-TYP-001, HARN-TYP-012

HARN-TYP-007

Category: TYP (Type checker)  ·  API stability: stable

initializer does not match the declared variable type

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type
  • See also: HARN-TYP-001, HARN-TYP-005

HARN-TYP-008

Category: TYP (Type checker)  ·  API stability: stable

closure return expression does not match its declared type

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type
  • See also: HARN-TYP-004

HARN-TYP-009

Category: TYP (Type checker)  ·  API stability: stable

field value does not match its declared type

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type
  • See also: HARN-TYP-001, HARN-TYP-022

HARN-TYP-010

Category: TYP (Type checker)  ·  API stability: stable

method receiver or result type is incompatible

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type
  • See also: HARN-TYP-001, HARN-TYP-018

HARN-TYP-011

Category: TYP (Type checker)  ·  API stability: stable

callable does not accept type arguments

unsupported)

HARN-TYP-012

Category: TYP (Type checker)  ·  API stability: stable

type argument does not satisfy the generic parameter

mismatch)

HARN-TYP-013

Category: TYP (Type checker)  ·  API stability: stable

generic call has the wrong number of type arguments

HARN-TYP-014

Category: TYP (Type checker)  ·  API stability: stable

declaration has the wrong number of type parameters

What it means

A generic declaration (function, type alias, or struct) was written with a different number of type parameters than the use-site supplies. Harn refuses to silently fill in missing parameters or discard extra ones — the count must match exactly.

Example

fn pair<T>(a: T, b: T) -> [T; 2] { [a, b] }

// HARN-TYP-014: pair takes 1 type parameter, not 2
let xs = pair::<int, string>(1, "two")

How to fix

  • Supply exactly as many type arguments as the declaration declares, or omit the explicit list and let Harn infer them.
  • If the declaration itself is wrong, edit the <T, U, ...> list on the declaration to match the arity the callers expect.
  • For type aliases and structs, the same rule applies: Map<K, V> needs two arguments, not one and not three.

HARN-TYP-015

Category: TYP (Type checker)  ·  API stability: stable

type argument does not satisfy a where-clause constraint

HARN-TYP-016

Category: TYP (Type checker)  ·  API stability: stable

expression must be iterable

HARN-TYP-017

Category: TYP (Type checker)  ·  API stability: stable

subscript index type is invalid

  • Repair: casts/insert-explicit-conversion  ·  Safety: scope-local
  • Insert an explicit conversion or correct the operand type

HARN-TYP-018

Category: TYP (Type checker)  ·  API stability: stable

expression must be callable

HARN-TYP-019

Category: TYP (Type checker)  ·  API stability: stable

cast cannot be proven valid

  • Repair: casts/remove-unchecked  ·  Safety: scope-local
  • Remove the unchecked cast or guard it with a type test

HARN-TYP-020

Category: TYP (Type checker)  ·  API stability: stable

type name cannot be resolved

  • Repair: imports/fix-path  ·  Safety: scope-local
  • Replace the import path with a resolvable target

HARN-TYP-021

Category: TYP (Type checker)  ·  API stability: stable

variant type is used in an invalid position

HARN-TYP-022

Category: TYP (Type checker)  ·  API stability: stable

struct literal is invalid

HARN-TYP-023

Category: TYP (Type checker)  ·  API stability: stable

enum construction is invalid

HARN-TYP-024

Category: TYP (Type checker)  ·  API stability: stable

pattern binding is invalid for the expected type

HARN-TYP-025

Category: TYP (Type checker)  ·  API stability: stable

optional access is invalid for the receiver type

HARN-PAR-001

Category: PAR (Parser / lexer)  ·  API stability: stable

parser found an unexpected token

How to fix

  • Re-read the source around the highlighted span and restore the missing token(s).
  • If the surrounding construct is a multi-line expression, check brace / bracket balance.

HARN-PAR-002

Category: PAR (Parser / lexer)  ·  API stability: stable

parser reached end of file while expecting syntax

How to fix

  • Re-read the source around the highlighted span and restore the missing token(s).
  • If the surrounding construct is a multi-line expression, check brace / bracket balance.

HARN-PAR-003

Category: PAR (Parser / lexer)  ·  API stability: stable

lexer found an unexpected character

How to fix

  • Re-read the source around the highlighted span and restore the missing token(s).
  • If the surrounding construct is a multi-line expression, check brace / bracket balance.

HARN-PAR-004

Category: PAR (Parser / lexer)  ·  API stability: stable

string literal is unterminated

How to fix

  • Re-read the source around the highlighted span and restore the missing token(s).
  • If the surrounding construct is a multi-line expression, check brace / bracket balance.

HARN-PAR-005

Category: PAR (Parser / lexer)  ·  API stability: stable

block comment is unterminated

comment)

How to fix

  • Re-read the source around the highlighted span and restore the missing token(s).
  • If the surrounding construct is a multi-line expression, check brace / bracket balance.

HARN-PAR-006

Category: PAR (Parser / lexer)  ·  API stability: stable

integer literal is out of range for int (i64)

An integer literal must fit in a 64-bit signed integer (int), i.e. be in the range -9223372036854775808 ..= 9223372036854775807. Harn does not silently widen an out-of-range integer literal to a float, because that would lose both the exact value (distinct literals collapse onto the same float) and the int type.

How to fix

  • If you meant a floating-point value, write it with a decimal point or exponent so it lexes as a float (e.g. 9223372036854775808.0).
  • If you need the most negative int, build it by arithmetic — the sign is not part of the literal, so 9223372036854775808 overflows on its own: -9223372036854775807 - 1.
  • Otherwise the value genuinely does not fit in int; rework the computation to stay within range.

HARN-NAM-001

Category: NAM (Naming and resolution)  ·  API stability: stable

variable name cannot be resolved

  • Repair: bindings/rename-to-closest  ·  Safety: scope-local
  • Rename to the closest in-scope identifier
  • See also: HARN-NAM-002, HARN-NAM-010

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-002

Category: NAM (Naming and resolution)  ·  API stability: stable

function name cannot be resolved

  • Repair: bindings/rename-to-closest  ·  Safety: scope-local
  • Rename to the closest in-scope identifier
  • See also: HARN-NAM-008, HARN-NAM-010

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-003

Category: NAM (Naming and resolution)  ·  API stability: stable

attribute name is not recognized

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-004

Category: NAM (Naming and resolution)  ·  API stability: stable

field name does not exist on the target type

  • Repair: bindings/rename-to-closest  ·  Safety: scope-local
  • Rename to the closest in-scope identifier
  • See also: HARN-NAM-005, HARN-TYP-022

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-005

Category: NAM (Naming and resolution)  ·  API stability: stable

method name does not exist on the receiver type

  • Repair: bindings/rename-to-closest  ·  Safety: scope-local
  • Rename to the closest in-scope identifier
  • See also: HARN-NAM-004, HARN-TYP-018

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-006

Category: NAM (Naming and resolution)  ·  API stability: stable

argument name is duplicated

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-007

Category: NAM (Naming and resolution)  ·  API stability: stable

option key is not recognized

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-008

Category: NAM (Naming and resolution)  ·  API stability: stable

builtin name cannot be resolved

  • Repair: bindings/rename-to-closest  ·  Safety: scope-local
  • Rename to the closest in-scope identifier

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-009

Category: NAM (Naming and resolution)  ·  API stability: stable

function call targets a deprecated declaration

  • Repair: stdlib/migrate-renamed  ·  Safety: scope-local
  • Rename the call to the renamed stdlib symbol

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-010

Category: NAM (Naming and resolution)  ·  API stability: stable

declaration reference cannot be resolved

  • Repair: bindings/rename-to-closest  ·  Safety: scope-local
  • Rename to the closest in-scope identifier

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-011

Category: NAM (Naming and resolution)  ·  API stability: stable

attribute is attached to an unsupported declaration

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-012

Category: NAM (Naming and resolution)  ·  API stability: stable

attribute argument is invalid

How to fix

  • Define the missing name, import it, or fix the typo.
  • Confirm the symbol is exported by the module you're importing from.

HARN-NAM-101

Category: NAM (Naming and resolution)  ·  API stability: stable

main entrypoint must take a single harness: Harness parameter

  • Repair: bindings/thread-harness-needs-param  ·  Safety: surface-changing
  • Add a harness: Harness parameter where the stdio capability handle is required and update local callers

What it means

When a Harn program declares a top-level fn main, the runtime auto-invokes it with the script's Harness capability handle. The convention is therefore strict: the entrypoint must be exactly fn main(harness: Harness) { ... } — or fn main(_harness: Harness) { ... } when the handle is intentionally unused. It takes one parameter, named harness or _harness, typed Harness, no defaults, no rest.

Any other shape (zero parameters, a renamed parameter, a missing or non-Harness type annotation, extra parameters, or a default value) fails this check before bytecode is emitted, so the runtime never tries to bind a mismatched signature.

The Harness value gives the script typed access to its capability sub-handles via field access (harness.stdio, harness.term, harness.clock, harness.fs, harness.env, harness.random, harness.net, harness.process, harness.crypto, harness.system, harness.llm). Threading the handle through main replaces ambient stdio, terminal, clock, filesystem, environment, randomness, network, process, crypto, system, and LLM catalog globals.

How to fix

Rewrite the entrypoint with the canonical signature:

fn main(harness: Harness) {
  harness.stdio.println("Hello, world!")
}

If you do not need any capabilities — for example, a script that only does pure computation — prefix the parameter with _ to mark it deliberately unused:

fn main(_harness: Harness) {
  // pure logic …
}

If the function does not need to be the entrypoint, rename it (e.g. helper, run_once) so the convention does not apply.

HARN-CAP-001

Category: CAP (Capabilities)  ·  API stability: stable

capability payload is invalid

How to fix

  • Match the capability signature documented in the Harn capability spec.
  • If approval / receipt handling is required, wire it through human_approval or the equivalent before calling the capability.

HARN-CAP-002

Category: CAP (Capabilities)  ·  API stability: stable

human approval construct is missing policy

How to fix

  • Match the capability signature documented in the Harn capability spec.
  • If approval / receipt handling is required, wire it through human_approval or the equivalent before calling the capability.

HARN-CAP-003

Category: CAP (Capabilities)  ·  API stability: stable

human approval argument is invalid

argument)

How to fix

  • Match the capability signature documented in the Harn capability spec.
  • If approval / receipt handling is required, wire it through human_approval or the equivalent before calling the capability.

HARN-CAP-004

Category: CAP (Capabilities)  ·  API stability: stable

capability result must be checked

  • Repair: errors/check-or-rescue  ·  Safety: scope-local
  • Check the result or wrap the call in a rescue block
  • See also: HARN-RCV-001, HARN-RCV-002

How to fix

  • Match the capability signature documented in the Harn capability spec.
  • If approval / receipt handling is required, wire it through human_approval or the equivalent before calling the capability.

HARN-CAP-005

Category: CAP (Capabilities)  ·  API stability: stable

host capability operation is not declared

How to fix

  • Match the capability signature documented in the Harn capability spec.
  • If approval / receipt handling is required, wire it through human_approval or the equivalent before calling the capability.

HARN-CAP-006

Category: CAP (Capabilities)  ·  API stability: stable

host capability call must use a static operation name

name required)

How to fix

  • Match the capability signature documented in the Harn capability spec.
  • If approval / receipt handling is required, wire it through human_approval or the equivalent before calling the capability.

HARN-CAP-007

Category: CAP (Capabilities)  ·  API stability: stable

tool host capability binding is invalid

  • Repair: manual/review-capability-binding  ·  Safety: needs-human
  • Review the capability binding; the fix is not mechanical

How to fix

  • Match the capability signature documented in the Harn capability spec.
  • If approval / receipt handling is required, wire it through human_approval or the equivalent before calling the capability.

HARN-CAP-201

Category: CAP (Capabilities)  ·  API stability: stable

harness capability denied by active sandbox profile

What it means

A harness.fs.*, harness.env.*, harness.random.*, harness.net.*, harness.system.*, or harness.llm.* method was rejected by the active sandbox profile. Examples:

  • harness.fs.write_text("/etc/passwd", ...) from a script whose workspace_roots only include ./build/ — the path is outside the permitted set.
  • harness.net.get("https://example.com") from a script whose egress allowlist does not include example.com.
  • Any harness.* capability under SandboxProfile::OsHardened when the required platform mechanism is unavailable.

The runtime raises the rejection as a typed tool_rejected error so the harness method surface stays narrow — every script-visible capability tightens the same way at the same boundary, instead of each ambient builtin growing its own bespoke deny diagnostic.

When the requested operation can be evaluated against the profile ahead of time (literal path or URL argument, well-known method on a sub-handle), harn check and harn lint surface the same diagnostic at static-check time so callers don't have to actually execute the script to discover the denial.

How to fix

  • Widen the active sandbox profile via CapabilityPolicy::workspace_roots or the egress allowlist if the request is legitimate. The relevant policy lives in ~/.config/harn/policy.toml or the per-script CapabilityPolicy overlay.
  • Use harn graph --json to inspect which capabilities your script actually needs, then narrow the call site to those.
  • For tests, switch from Harness::real() to Harness::mock() / Harness::null() so the call is recorded without touching the host.

HARN-CAP-301

Category: CAP (Capabilities)  ·  API stability: stable

child agent effect set exceeds the parent's declared effects

  • Repair: policy/narrow-child-effects  ·  Safety: surface-changing
  • Narrow the child agent's effects to a subset of the parent's, or widen the parent's declared effects
  • See also: HARN-CAP-001, HARN-CAP-007

What it means

A spawned child agent requests typed side-effects (harness.net.*, harness.fs.*, llm_call, tool dispatch, ...) that are not part of the parent agent's declared effect set. The dispatcher (and harn check's static analyzer) enforce that a child's effect set must be a subset of the parent's so an over-delegated child can never escape its parent's trust boundary.

Specifically: at least one effect on the child handoff is not covered by any effect declared on the parent. Coverage is structural:

  • Kind must match by family (stdio, fs, net, llm, tool, hostcall, persona, spawn).
  • Scope must be at least as permissive on the parent (read/observewritemutate).
  • Resource, when declared on the parent, must match the child's exactly. A parent with no resource covers any child resource of the same kind/scope family.

This diagnostic surfaces from two paths and they are intentionally identical:

  • Static: harn check derives parent and child effect sets via the same capability analysis that backs harn graph --json and emits HARN-CAP-301 when a child statically out-grants its parent.
  • Runtime: at spawn time the dispatcher folds the parent's current_execution_policy() into an effect set, compares it against the child's computed effects, and refuses the spawn with a typed EffectInheritanceViolation deny event. The event payload carries the same HARN-CAP-301 code and policy/narrow-child-effects repair id.

How to fix

The repair id is policy/narrow-child-effects. Two shapes are typically valid:

  1. Narrow the child — remove the over-granted calls from the child pipeline body, or guard them behind a capability the parent already declares. This is the safe default; the child stops asking for what it does not need.
  2. Widen the parent — declare the missing effect on the parent pipeline (e.g. add a real harness.net.get(...) call in the parent's entrypoint, or extend the parent's policy.capabilities map). Only apply this when widening the parent's trust surface is itself an intentional design change — it touches a public surface.

Both shapes are marked safety: surface-changing, so harn fix --apply --safety surface-changing will dispatch the chosen repair.

Stability

The matched EffectInheritanceViolation runtime payload's _type discriminator (effect_inheritance_violation) is part of the stable contract.

HARN-LLM-001

Category: LLM (LLM calls)  ·  API stability: stable

LLM option key is not recognized

How to fix

  • Pass a schema: option that validates the model output, with schema_retries: as appropriate.
  • Drop or rename deprecated options to the names listed in the LLM call quickref.
  • Pick capability flags (tool_calling: true, etc.) instead of branching on provider: identity.

HARN-LLM-002

Category: LLM (LLM calls)  ·  API stability: stable

LLM option key is deprecated

  • Repair: llm/migrate-deprecated-option  ·  Safety: scope-local
  • Replace the deprecated option with its supported equivalent
  • See also: HARN-LLM-001

How to fix

  • Pass a schema: option that validates the model output, with schema_retries: as appropriate.
  • Drop or rename deprecated options to the names listed in the LLM call quickref.
  • Pick capability flags (tool_calling: true, etc.) instead of branching on provider: identity.

HARN-LLM-003

Category: LLM (LLM calls)  ·  API stability: stable

LLM call is missing schema validation

  • Repair: llm/add-schema  ·  Safety: surface-changing
  • Add a typed output schema to the LLM call
  • See also: HARN-LLM-004, HARN-LLM-001

How to fix

  • Pass a schema: option that validates the model output, with schema_retries: as appropriate.
  • Drop or rename deprecated options to the names listed in the LLM call quickref.
  • Pick capability flags (tool_calling: true, etc.) instead of branching on provider: identity.

HARN-LLM-004

Category: LLM (LLM calls)  ·  API stability: stable

LLM schema option is invalid

How to fix

  • Pass a schema: option that validates the model output, with schema_retries: as appropriate.
  • Drop or rename deprecated options to the names listed in the LLM call quickref.
  • Pick capability flags (tool_calling: true, etc.) instead of branching on provider: identity.

HARN-LLM-005

Category: LLM (LLM calls)  ·  API stability: stable

prompt branches on provider identity instead of capability flags

  • Repair: llm/use-capability-flag  ·  Safety: capability-changing
  • Branch on a capability flag instead of provider identity
  • See also: HARN-PRM-004

How to fix

  • Pass a schema: option that validates the model output, with schema_retries: as appropriate.
  • Drop or rename deprecated options to the names listed in the LLM call quickref.
  • Pick capability flags (tool_calling: true, etc.) instead of branching on provider: identity.

HARN-ORC-001

Category: ORC (Orchestration constructs)  ·  API stability: stable

orchestration construct has invalid arity

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-002

Category: ORC (Orchestration constructs)  ·  API stability: stable

orchestration construct argument has invalid type

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-003

Category: ORC (Orchestration constructs)  ·  API stability: stable

agent declaration is invalid

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-004

Category: ORC (Orchestration constructs)  ·  API stability: stable

workflow declaration is invalid

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-005

Category: ORC (Orchestration constructs)  ·  API stability: stable

tool declaration is invalid

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-006

Category: ORC (Orchestration constructs)  ·  API stability: stable

pipeline declaration is invalid

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-007

Category: ORC (Orchestration constructs)  ·  API stability: stable

select construct is invalid

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-008

Category: ORC (Orchestration constructs)  ·  API stability: stable

statement cannot be reached

  • Repair: control-flow/remove-dead  ·  Safety: behavior-preserving
  • Remove the unreachable code

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-009

Category: ORC (Orchestration constructs)  ·  API stability: stable

Flow invariant attribute set is invalid

invalid)

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-010

Category: ORC (Orchestration constructs)  ·  API stability: stable

execution target path cannot be found

What it means

An orchestration construct — agent / workflow / pipeline / tool definition, or a select block — does not satisfy the structural rules Harn enforces. These constructs carry runtime semantics that depend on a small set of well-formed shapes.

How to fix

  • Re-read the orchestration construct's spec section and align the arity / type / structure.

HARN-ORC-011

Category: ORC (Orchestration constructs)  ·  API stability: stable

a self-deadlock acquire would block forever

What it means

The VM detected an acquire that can never succeed and would otherwise block forever, so it surfaced an error instead of hanging. Two deterministic, provably-unresolvable cases are caught:

  • Re-entrant mutex. A lexical mutex { ... } block acquires a non-reentrant, capacity-1 lock. Entering a second mutex block on the same key while the first is still held — directly or through a called function — can never be granted, because the sole permit holder is the task that is now waiting on it.
  • Self-join. A task awaits its own join handle. The handle only resolves when the task finishes, so waiting on it from inside the task itself can never complete.

Harn's static checks (like Rust's borrow checker) prevent data races but not deadlocks; this runtime guard is the analogue of the Go runtime's "all goroutines are asleep — deadlock!" detection for the cases that are provable with no false positives.

How to fix

  • Do not nest mutex { ... } blocks that resolve to the same lock, and avoid calling a function that opens a mutex block from inside another one. Restructure so the lock is released before it is acquired again, or hold a single lock around the whole critical section.
  • Never await the handle of the current task. Await it from the task that spawned it instead.

This error is non-retryable: it indicates a structural concurrency bug, not a transient failure.

HARN-ORC-012

Category: ORC (Orchestration constructs)  ·  API stability: stable

a wait-for graph cycle would block forever

What it means

The VM detected that every active task in the current execution tree is waiting, and the outstanding channel operations cannot match a sender with a receiver. Without this guard the run would block forever.

This check only fires when the runtime can prove the wait is closed-world: running tasks, sleeping tasks, time-bounded selects, and deadline { ... } scopes keep the guard from reporting a deadlock.

How to fix

Make sure every blocking receive has a task that can still send to that channel, and every blocking send on a full channel has a task that can still receive from it. If the wait is intentionally optional, use try_receive, select timeout, channel_select(..., timeout_ms), or wrap the operation in a deadline { ... } block.

This error is non-retryable: it indicates a structural concurrency bug, not a transient failure.

HARN-STD-001

Category: STD (Stdlib usage)  ·  API stability: stable

stdlib symbol has been renamed or deprecated

  • Repair: stdlib/migrate-renamed  ·  Safety: scope-local
  • Rename the call to the renamed stdlib symbol

What it means

A stdlib symbol is being used in a way Harn does not support, or has been renamed / deprecated since the script was written. The stdlib is the live source of truth for what's available.

How to fix

  • Switch to the supported / renamed stdlib API listed in the diagnostic help text.

HARN-STD-002

Category: STD (Stdlib usage)  ·  API stability: stable

stdlib call is invalid

What it means

A stdlib symbol is being used in a way Harn does not support, or has been renamed / deprecated since the script was written. The stdlib is the live source of truth for what's available.

How to fix

  • Switch to the supported / renamed stdlib API listed in the diagnostic help text.

HARN-STD-003

Category: STD (Stdlib usage)  ·  API stability: stable

builtin call has invalid arity

What it means

A stdlib symbol is being used in a way Harn does not support, or has been renamed / deprecated since the script was written. The stdlib is the live source of truth for what's available.

How to fix

  • Switch to the supported / renamed stdlib API listed in the diagnostic help text.

HARN-STD-101

Category: STD (Stdlib usage)  ·  API stability: stable

public stdlib function is missing declared metadata

  • Repair: doc/add-stdlib-metadata  ·  Safety: behavior-preserving
  • Add @effects, @allocation, @errors, @api_stability, and @example fields to the stdlib function's doc block

What it means

Every public stdlib function ships with a declarative metadata block above its pub fn declaration so that harn graph --json, the LSP hover, generated docs, and downstream agents can read a single source of truth for the function's runtime contract.

The required fields are:

FieldPurpose
@effectsCapabilities the function may touch (e.g. fs.read, stdio.write, llm.call). [] means pure.
@allocationAllocation profile — typically stack-only or heap.
@errorsError variants the function may surface. [] means infallible.
@api_stabilityStability promise — stable, experimental, or deprecated.
@exampleMinimal usage example (verbatim Harn).

The lint warns when a pub fn declared inside an embedded stdlib module (crates/harn-stdlib/src/stdlib/**/*.harn) is missing one or more of these fields from the /** ... */ HarnDoc block immediately above it.

How to fix

Add the missing fields to the function's HarnDoc block:

/**
 * Render the project README.
 *
 * @effects: [fs.read, fs.write]
 * @allocation: heap
 * @errors: [FileNotFound, PermissionDenied]
 * @api_stability: stable
 * @example: render_readme("README.md")
 */
pub fn render_readme(path: string) -> Result<string, FsError> { ... }

The lint considers @effects: [] and @errors: [] valid declarations — they explicitly assert "no effects" and "infallible" respectively, which is what agents need to read out of the graph.

HARN-PRM-001

Category: PRM (Prompt templates)  ·  API stability: stable

prompt template cannot be parsed

What it means

A prompt template (.harn.prompt / .prompt) failed validation, either because the template body is malformed or because it references the model surface in a way that violates Harn's prompt safety rules.

How to fix

  • Fix the template syntax ({{ }}, {% %} are the only structural delimiters).
  • Replace identity-based branching with capability flags from the LLM call options.

HARN-PRM-002

Category: PRM (Prompt templates)  ·  API stability: stable

prompt template has too many capability-aware branches

  • Repair: manual/needs-human  ·  Safety: needs-human
  • Plan a human-led change; auto-apply is not safe here
  • See also: HARN-LNT-044

What it means

A prompt template (.harn.prompt / .prompt) failed validation, either because the template body is malformed or because it references the model surface in a way that violates Harn's prompt safety rules.

How to fix

  • Fix the template syntax ({{ }}, {% %} are the only structural delimiters).
  • Replace identity-based branching with capability flags from the LLM call options.

HARN-PRM-003

Category: PRM (Prompt templates)  ·  API stability: stable

prompt construction risks direct injection

  • Repair: prompts/escape-injection  ·  Safety: scope-local
  • Pass the untrusted input through a structured placeholder
  • See also: HARN-LNT-026

What it means

A prompt template (.harn.prompt / .prompt) failed validation, either because the template body is malformed or because it references the model surface in a way that violates Harn's prompt safety rules.

How to fix

  • Fix the template syntax ({{ }}, {% %} are the only structural delimiters).
  • Replace identity-based branching with capability flags from the LLM call options.

HARN-PRM-004

Category: PRM (Prompt templates)  ·  API stability: stable

prompt template branches on provider identity

  • Repair: llm/use-capability-flag  ·  Safety: capability-changing
  • Branch on a capability flag instead of provider identity
  • See also: HARN-LLM-005, HARN-LNT-046

branch)

What it means

A prompt template (.harn.prompt / .prompt) failed validation, either because the template body is malformed or because it references the model surface in a way that violates Harn's prompt safety rules.

How to fix

  • Fix the template syntax ({{ }}, {% %} are the only structural delimiters).
  • Replace identity-based branching with capability flags from the LLM call options.

HARN-PRM-005

Category: PRM (Prompt templates)  ·  API stability: stable

prompt references a tool outside the declared surface

  • Repair: prompts/add-tool-to-surface  ·  Safety: surface-changing
  • Add the referenced tool to the declared tool surface

What it means

A prompt template (.harn.prompt / .prompt) failed validation, either because the template body is malformed or because it references the model surface in a way that violates Harn's prompt safety rules.

How to fix

  • Fix the template syntax ({{ }}, {% %} are the only structural delimiters).
  • Replace identity-based branching with capability flags from the LLM call options.

HARN-PRM-006

Category: PRM (Prompt templates)  ·  API stability: stable

prompt references a deferred tool without tool search

  • Repair: prompts/add-tool-to-surface  ·  Safety: surface-changing
  • Add the referenced tool to the declared tool surface

deferred reference)

What it means

A prompt template (.harn.prompt / .prompt) failed validation, either because the template body is malformed or because it references the model surface in a way that violates Harn's prompt safety rules.

How to fix

  • Fix the template syntax ({{ }}, {% %} are the only structural delimiters).
  • Replace identity-based branching with capability flags from the LLM call options.

HARN-PRM-007

Category: PRM (Prompt templates)  ·  API stability: stable

prompt or template target cannot be found

What it means

A prompt template (.harn.prompt / .prompt) failed validation, either because the template body is malformed or because it references the model surface in a way that violates Harn's prompt safety rules.

How to fix

  • Fix the template syntax ({{ }}, {% %} are the only structural delimiters).
  • Replace identity-based branching with capability flags from the LLM call options.

HARN-MOD-001

Category: MOD (Modules and exports)  ·  API stability: stable

module import cannot be resolved

  • Repair: imports/fix-path  ·  Safety: scope-local
  • Replace the import path with a resolvable target
  • See also: HARN-IMP-001, HARN-IMP-002

What it means

A module-level import declaration cannot be satisfied or has been authored in a non-canonical form. The module graph must resolve cleanly before any further checks.

How to fix

  • Confirm the import path resolves on disk and the imported symbol is exported.
  • Run harn lint --fix to auto-sort / dedupe import groups.

HARN-MOD-002

Category: MOD (Modules and exports)  ·  API stability: stable

module import is unused

  • Repair: imports/remove-unused  ·  Safety: behavior-preserving
  • Remove the unused import
  • See also: HARN-LNT-017

What it means

A module-level import declaration cannot be satisfied or has been authored in a non-canonical form. The module graph must resolve cleanly before any further checks.

How to fix

  • Confirm the import path resolves on disk and the imported symbol is exported.
  • Run harn lint --fix to auto-sort / dedupe import groups.

HARN-MOD-003

Category: MOD (Modules and exports)  ·  API stability: stable

module imports are not in canonical order

  • Repair: imports/reorder  ·  Safety: format-only
  • Reorder imports into canonical grouping

What it means

A module-level import declaration cannot be satisfied or has been authored in a non-canonical form. The module graph must resolve cleanly before any further checks.

How to fix

  • Confirm the import path resolves on disk and the imported symbol is exported.
  • Run harn lint --fix to auto-sort / dedupe import groups.

HARN-MOD-004

Category: MOD (Modules and exports)  ·  API stability: stable

module export is invalid

What it means

A module-level import declaration cannot be satisfied or has been authored in a non-canonical form. The module graph must resolve cleanly before any further checks.

How to fix

  • Confirm the import path resolves on disk and the imported symbol is exported.
  • Run harn lint --fix to auto-sort / dedupe import groups.

HARN-MOD-005

Category: MOD (Modules and exports)  ·  API stability: stable

module imports expose colliding names

What it means

A module-level import declaration cannot be satisfied or has been authored in a non-canonical form. The module graph must resolve cleanly before any further checks.

How to fix

  • Confirm the import path resolves on disk and the imported symbol is exported.
  • Run harn lint --fix to auto-sort / dedupe import groups.

HARN-MOD-006

Category: MOD (Modules and exports)  ·  API stability: stable

module re-exports conflict

What it means

A module-level import declaration cannot be satisfied or has been authored in a non-canonical form. The module graph must resolve cleanly before any further checks.

How to fix

  • Confirm the import path resolves on disk and the imported symbol is exported.
  • Run harn lint --fix to auto-sort / dedupe import groups.

HARN-RMD-001

Category: RMD (Reminder lifecycle)  ·  API stability: stable

reminder lifecycle option key is not recognized

Reminder lifecycle option tables reject unknown keys so reminder shape stays stable across transcript transforms, hooks, and bridge integrations.

Use only the documented transcript.inject_reminder keys: body, tags, dedupe_key, ttl_turns, preserve_on_compact, propagate, and role_hint.

For transcript.clear_reminders, use at least one selector from id, tag, or dedupe_key.

HARN-RMD-002

Category: RMD (Reminder lifecycle)  ·  API stability: stable

reminder payload shape is invalid

The reminder payload shape is invalid.

session/remind expects a typed reminder object, not a user-message payload. Provide a non-empty body, use string tags, a positive integer ttl_turns when present, boolean preserve_on_compact, and one of the documented propagate and role_hint values. Put host-specific extension fields under _meta.

HARN-RMD-003

Category: RMD (Reminder lifecycle)  ·  API stability: stable

user_block reminder role hint is not supported by the selected provider

The pipeline hardcodes role_hint: "user_block" while also selecting an LLM provider/model route that cannot render reminders as Anthropic-style user content blocks or OpenAI developer-role messages.

Use role_hint: "system" or role_hint: "developer" for provider-neutral reminders, or branch on provider capability flags before selecting a provider-specific reminder shape.

HARN-RMD-004

Category: RMD (Reminder lifecycle)  ·  API stability: stable

discardable reminder has no TTL

A reminder literal sets preserve_on_compact: false while leaving ttl_turns unset or nil. That reminder can live forever during normal turns, but it is allowed to disappear at the next transcript compaction.

Set a finite ttl_turns for short-lived nudges, or set preserve_on_compact: true when the reminder must survive compaction.

HARN-RMD-005

Category: RMD (Reminder lifecycle)  ·  API stability: stable

reminder propagate value is not recognized

A reminder specified an unsupported propagate value. Reminder propagation must be one of all, session, or none.

Use all for reminders that should follow child agents, session for the current session only, and none for reminders that should never propagate.

Example fix:

transcript.inject_reminder(transcript(), {
  body: "Check the task ledger before continuing.",
  propagate: "session",
})

HARN-RMD-006

Category: RMD (Reminder lifecycle)  ·  API stability: stable

reminder provider returned a malformed reminder spec

A reminder provider closure returned a value that could not be parsed as a ReminderSpec. Provider closures may return nil, a reminder spec, an effect such as {reminder: {...}}, or a list of those effects.

Return a dict with a non-empty body and only supported reminder fields.

Example fix:

register_reminder_provider({
  id: "custom",
  subscribes_to: ["session_idle"],
  evaluate: { _ctx ->
    return {reminder: {body: "Re-check current session state.", ttl_turns: 1}}
  },
})

HARN-RMD-007

Category: RMD (Reminder lifecycle)  ·  API stability: stable

too many reminder providers are enabled

An agent_loop enables more than eight distinct reminder providers. Many providers can inject overlapping ambient context and increase prompt size.

Disable providers that are not useful for the loop, or split the loop into smaller stages with different reminder settings.

Example fix:

agent_loop(task, nil, {
  reminders: {providers: ["token_pressure", "idle_nudge"]},
})

HARN-RMD-008

Category: RMD (Reminder lifecycle)  ·  API stability: stable

hook event does not support reminder effects

A hook handler returned a reminder effect from a lifecycle event that cannot inject reminders. Worker lifecycle events are observational and must not mutate the active transcript with reminder effects.

Move the reminder to a session, tool, step, or persona hook that runs at a turn-boundary mutation point.

Example fix:

register_session_hook("post_turn", { _event ->
  return {reminder: {body: "Review worker progress before continuing."}}
})

HARN-SUS-001

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

suspend_agent target worker is not running

suspend_agent(...) can only create a new cooperative suspension for a running worker. A worker that is awaiting input, completed, failed, cancelled, or interrupted no longer has a running turn boundary where a suspend checkpoint can be installed.

Use the worker summary status to branch before suspending. For terminal workers, spawn a fresh worker instead. Calling suspend_agent(...) again on an already suspended worker remains an idempotent summary read.

HARN-SUS-002

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

ResumeConditions validation failed

ResumeConditions did not match the supported shape for a suspended agent. The object may contain trigger, timeout, and on_event. Trigger entries must parse as trigger specs, timeout entries need a positive duration_minutes, and event entries must be valid runtime event topics.

Validate untrusted condition tables with parse_resume_conditions(...) or agent_await_resumption(...) before passing them to suspend_agent(...).

HARN-SUS-003

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

resume_agent target worker is not suspended

resume_agent(...) was called on a live worker that is not currently in the suspended state. Warm resume is only meaningful for workers with an active suspension envelope.

Check the worker summary before resuming. Use send_input(...) for workers that are awaiting input, inspect terminal summaries directly, or load a snapshot path when you only need to restore persisted state.

HARN-SUS-004

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

resume snapshot cannot be loaded or used

resume_agent(...) could not load the requested snapshot, or the snapshot was not usable as a worker state. The path may be missing, stale, unreadable, or from an incompatible worker-state format.

Use the snapshot_path from the latest worker summary and keep the worker state directory available across process restarts. If the snapshot belongs to an older incompatible runtime, spawn a replacement worker instead of resuming.

HARN-SUS-005

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

agent_await_resumption was invoked outside agent_loop structural handling

The model-facing agent_await_resumption tool is structural. agent_loop intercepts that tool call, records audit metadata, and turns it into a suspend checkpoint. Invoking the tool handler directly bypasses that control flow, so Harn rejects it.

Call agent_await_resumption(reason, conditions?) only to build or normalize the request shape, or let an agent_loop turn handle the lifecycle tool call.

HARN-SUS-006

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

concurrent resume changed the worker before resume could complete

A resume operation started while the worker looked suspended, but another operator, trigger, or timeout changed the worker state before the resume could finish. Harn rejects the later resume so callers do not accidentally treat a race as a successful wake-up.

Refresh the worker summary and retry only if the worker is still suspended. For trigger-driven resumes, ensure only one trigger or timeout path remains armed for the suspension.

HARN-SUS-007

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

ResumeConditions trigger could not be registered

The conditions.trigger entry was valid enough to request an auto-resume binding, but Harn could not register or resolve the trigger in the live dispatcher registry.

Check the trigger kind, event matchers, and registry availability. Prefer normalizing the full ResumeConditions table before suspension so shape errors surface as HARN-SUS-002.

HARN-SUS-008

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

resume timeout action is unsupported

An auto-resume timeout used an on_timeout action Harn does not implement. Supported actions are resume_with_summary, resume_with_input, and fail.

Use parse_resume_conditions(...) to normalize timeout settings before suspending, or update the timeout table to one of the supported actions.

HARN-SUS-009

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

resume input failed agent_loop input validation

resume_agent(...) received resume input that could not be converted into a non-empty task prompt for the resumed agent loop.

Pass nil when resuming without new input, or pass a non-empty string or value whose string form is suitable as the next task prompt.

HARN-SUS-010

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

closed suspended worker cannot be resumed

The target worker was closed or cancelled after being suspended. Closing a worker removes the suspension envelope and rejects future resume attempts against that live worker handle.

Treat the worker as terminal. Spawn a new worker, or restore an explicit snapshot path only when you intentionally want to inspect persisted state.

HARN-SUS-011

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

replay resume input hash diverges from journaled suspension

The replay runtime computed a different resume-input fingerprint than the one captured in the original run's [ResumptionReceipt]. Lifecycle replay must be deterministic: the second run must feed the suspended worker the exact same payload it received the first time, because the worker's post-resume trajectory was hashed into the journaled state.

Common causes:

  • A pipeline that used to depend on wall-clock time or another non-deterministic input now produces a different resume payload on replay. Capture the payload itself (or use mock_time(...)) so the replayed runtime can reproduce the original value.
  • The journal entry was edited after the original run completed. The signed timestamp on the receipt detects this — verify the receipt's signature with verify_lifecycle_receipt_signature(...) before blaming the runtime.
  • The settlement agent (drain phase) changed its mind and produced a different resume input. Record a fresh ResumptionReceipt in the current run instead of replaying the stale one.

If the new payload is intentionally different (eg. you are running a deliberate counterfactual, not a determinism replay), open the trace as a fresh recording rather than feeding it back through the replay oracle.

HARN-SUS-012

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

replay drain decision prompt hash diverges from journaled receipt

The replay runtime tried to memoize a settlement-agent drain decision against a [DrainDecisionReceipt] whose prompt_hash does not match the candidate prompt the second run computed. Drain decisions are journaled so that replay can skip the settlement agent's LLM call — but if the prompt drifts, the recorded action no longer reflects what the agent would actually decide.

Common causes:

  • The pipeline's settlement-agent prompt template or its inputs (the unsettled-state snapshot, the budget summary, the worker list) changed between record and replay. Either re-record the trace or roll the template back to its recorded form.
  • The drain item set itself changed shape (eg. a new suspended subagent appeared on replay). Fix the upstream determinism gap first, then the drain receipt will line up.

The recorded receipt is still safe to inspect via lifecycle_receipts_snapshot(), and its signed timestamp tells you when the original decision was minted. Treat the mismatch as a signal that the replay is no longer a determinism check.

HARN-SUS-013

Category: SUS (Suspend / resume lifecycle)  ·  API stability: stable

lifecycle receipt signed timestamp failed verification

A [SuspensionReceipt], [ResumptionReceipt], or [DrainDecisionReceipt] carries a SignedLifecycleTimestamp whose HMAC signature does not match the receipt's identifying fields under the per-process signing salt.

The signature binds (kind, at_ms, subject_id, initiator_id), so any of the following will trip this diagnostic:

  • The receipt was minted by a different harn process and is now being verified after a restart. Per-process salts are intentional — cross-process verification requires migrating to the longer-lived provenance chain (see build_signed_receipt).
  • The journal entry was edited after the fact (eg. someone hand-tweaked at_ms or initiator_id in the on-disk record). The replay oracle rejects the tampered receipt before relying on it.
  • The signing algorithm or key id changed across a Harn upgrade. The current algorithm is hmac-sha256 with key id local-session.

If the original process is gone but you still need to read the receipts, treat the on-disk payloads as advisory only — the unsigned fields (handle, reason, input_hash, action) are still informational, but replay_resume_input / replay_drain_decision will refuse to memoize against an unverified receipt.

HARN-LNT-001

Category: LNT (Lint rules)  ·  API stability: stable

renamed stdlib symbol lint

  • Repair: stdlib/migrate-renamed  ·  Safety: scope-local
  • Rename the call to the renamed stdlib symbol
  • See also: HARN-STD-001

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-002

Category: LNT (Lint rules)  ·  API stability: stable

cyclomatic complexity lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-003

Category: LNT (Lint rules)  ·  API stability: stable

naming convention lint

  • Repair: style/rename-to-convention  ·  Safety: surface-changing
  • Rename to match the casing convention for this kind

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-004

Category: LNT (Lint rules)  ·  API stability: stable

eager collection conversion lint

  • Repair: collections/prefer-lazy  ·  Safety: scope-local
  • Replace the eager collection step with a lazy variant

conversion)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-005

Category: LNT (Lint rules)  ·  API stability: stable

redundant clone lint

  • Repair: clones/remove-redundant  ·  Safety: behavior-preserving
  • Remove the redundant clone

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-006

Category: LNT (Lint rules)  ·  API stability: stable

long-running workflow cleanup lint

  • Repair: manual/needs-human  ·  Safety: needs-human
  • Plan a human-led change; auto-apply is not safe here

cleanup)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-007

Category: LNT (Lint rules)  ·  API stability: stable

MCP tool annotations lint

  • Repair: manual/needs-human  ·  Safety: needs-human
  • Plan a human-led change; auto-apply is not safe here

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-008

Category: LNT (Lint rules)  ·  API stability: stable

PR open without secret scan lint

scan)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-009

Category: LNT (Lint rules)  ·  API stability: stable

shadow variable lint

  • Repair: bindings/rename-shadow  ·  Safety: scope-local
  • Rename the shadowing binding to a distinct name

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-010

Category: LNT (Lint rules)  ·  API stability: stable

persona hook target lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-011

Category: LNT (Lint rules)  ·  API stability: stable

dead code after return lint

  • Repair: control-flow/remove-dead  ·  Safety: behavior-preserving
  • Remove the unreachable code

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-012

Category: LNT (Lint rules)  ·  API stability: stable

let then return lint

  • Repair: control-flow/flatten  ·  Safety: behavior-preserving
  • Flatten the unnecessary control flow construct

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-013

Category: LNT (Lint rules)  ·  API stability: stable

unhandled approval result lint

  • Repair: errors/check-or-rescue  ·  Safety: scope-local
  • Check the result or wrap the call in a rescue block

result)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-014

Category: LNT (Lint rules)  ·  API stability: stable

unused variable lint

  • Repair: bindings/rename-unused  ·  Safety: behavior-preserving
  • Prefix the unused binding with _ to silence the lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-015

Category: LNT (Lint rules)  ·  API stability: stable

unused pattern binding lint

  • Repair: bindings/rename-unused  ·  Safety: behavior-preserving
  • Prefix the unused binding with _ to silence the lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-016

Category: LNT (Lint rules)  ·  API stability: stable

unused parameter lint

  • Repair: bindings/rename-unused  ·  Safety: behavior-preserving
  • Prefix the unused binding with _ to silence the lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-017

Category: LNT (Lint rules)  ·  API stability: stable

unused import lint

  • Repair: imports/remove-unused  ·  Safety: behavior-preserving
  • Remove the unused import
  • See also: HARN-MOD-002

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-018

Category: LNT (Lint rules)  ·  API stability: stable

mutable never reassigned lint

  • Repair: bindings/make-immutable  ·  Safety: behavior-preserving
  • Drop mut since the binding is never reassigned
  • See also: HARN-OWN-002

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-019

Category: LNT (Lint rules)  ·  API stability: stable

unused function lint

  • Repair: declarations/remove-unused  ·  Safety: surface-changing
  • Remove the unused declaration

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-020

Category: LNT (Lint rules)  ·  API stability: stable

unused type lint

  • Repair: declarations/remove-unused  ·  Safety: surface-changing
  • Remove the unused declaration

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-021

Category: LNT (Lint rules)  ·  API stability: stable

persona body must call steps lint

steps)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-022

Category: LNT (Lint rules)  ·  API stability: stable

undefined function lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-023

Category: LNT (Lint rules)  ·  API stability: stable

pipeline return type lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-024

Category: LNT (Lint rules)  ·  API stability: stable

missing harndoc lint

  • Repair: doc/add-harndoc  ·  Safety: behavior-preserving
  • Add a /// doc comment describing this declaration

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-025

Category: LNT (Lint rules)  ·  API stability: stable

assert outside test lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-026

Category: LNT (Lint rules)  ·  API stability: stable

prompt injection risk lint

  • Repair: prompts/escape-injection  ·  Safety: scope-local
  • Pass the untrusted input through a structured placeholder
  • See also: HARN-PRM-003

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-027

Category: LNT (Lint rules)  ·  API stability: stable

connector effect policy lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-028

Category: LNT (Lint rules)  ·  API stability: stable

unnecessary cast lint

  • Repair: casts/remove-redundant  ·  Safety: behavior-preserving
  • Remove the redundant cast

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-029

Category: LNT (Lint rules)  ·  API stability: stable

untyped dict access lint

  • Repair: types/add-shape-annotation  ·  Safety: surface-changing
  • Annotate the dict with a concrete shape type

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-030

Category: LNT (Lint rules)  ·  API stability: stable

constant logical operand lint

  • Repair: expressions/simplify  ·  Safety: behavior-preserving
  • Simplify the expression to its canonical form

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-031

Category: LNT (Lint rules)  ·  API stability: stable

pointless comparison lint

  • Repair: expressions/simplify  ·  Safety: behavior-preserving
  • Simplify the expression to its canonical form

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

NaN caveat

A self-comparison such as x == x or x != x is not constant when x is a NaN float: x == x is false and x != x is true for NaN (and the same holds element-wise for lists/dicts containing a NaN). The lint therefore only offers an auto-fix when the operand provably cannot be NaN (a non-float literal, or a list/dict built only from such literals). When the operand could be a float the lint still warns — a self-comparison is usually a typo — but leaves the code untouched and points you at is_nan(...), the idiomatic NaN test.

HARN-LNT-032

Category: LNT (Lint rules)  ·  API stability: stable

comparison to bool lint

  • Repair: expressions/simplify  ·  Safety: behavior-preserving
  • Simplify the expression to its canonical form

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-033

Category: LNT (Lint rules)  ·  API stability: stable

invalid binary operator literal lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-034

Category: LNT (Lint rules)  ·  API stability: stable

redundant nil ternary lint

  • Repair: expressions/simplify  ·  Safety: behavior-preserving
  • Simplify the expression to its canonical form

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-035

Category: LNT (Lint rules)  ·  API stability: stable

empty block lint

  • Repair: blocks/remove-empty  ·  Safety: scope-local
  • Remove the empty block or fill in an explicit body

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-036

Category: LNT (Lint rules)  ·  API stability: stable

unnecessary else return lint

  • Repair: control-flow/flatten  ·  Safety: behavior-preserving
  • Flatten the unnecessary control flow construct

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-037

Category: LNT (Lint rules)  ·  API stability: stable

duplicate match arm lint

  • Repair: match/remove-duplicate-arm  ·  Safety: behavior-preserving
  • Remove the duplicated match arm
  • See also: HARN-MAT-002

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-038

Category: LNT (Lint rules)  ·  API stability: stable

require in test lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-039

Category: LNT (Lint rules)  ·  API stability: stable

break outside loop lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-040

Category: LNT (Lint rules)  ·  API stability: stable

template parse lint

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-041

Category: LNT (Lint rules)  ·  API stability: stable

blank line between items lint

  • Repair: format/reformat  ·  Safety: format-only
  • Apply canonical formatting

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-042

Category: LNT (Lint rules)  ·  API stability: stable

trailing comma lint

  • Repair: format/reformat  ·  Safety: format-only
  • Apply canonical formatting

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-043

Category: LNT (Lint rules)  ·  API stability: stable

unnecessary parentheses lint

  • Repair: format/reformat  ·  Safety: format-only
  • Apply canonical formatting

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-044

Category: LNT (Lint rules)  ·  API stability: stable

template variant explosion lint

  • Repair: manual/needs-human  ·  Safety: needs-human
  • Plan a human-led change; auto-apply is not safe here
  • See also: HARN-PRM-002

explosion)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-045

Category: LNT (Lint rules)  ·  API stability: stable

require file header lint

  • Repair: format/reformat  ·  Safety: format-only
  • Apply canonical formatting

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-046

Category: LNT (Lint rules)  ·  API stability: stable

template provider identity branch lint

  • Repair: llm/use-capability-flag  ·  Safety: capability-changing
  • Branch on a capability flag instead of provider identity
  • See also: HARN-PRM-004

identity branch)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-047

Category: LNT (Lint rules)  ·  API stability: stable

import order lint

  • Repair: imports/reorder  ·  Safety: format-only
  • Reorder imports into canonical grouping

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-048

Category: LNT (Lint rules)  ·  API stability: stable

prefer optional shorthand lint

  • Repair: expressions/simplify  ·  Safety: behavior-preserving
  • Simplify the expression to its canonical form

shorthand)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-049

Category: LNT (Lint rules)  ·  API stability: stable

legacy doc comment lint

  • Repair: doc/migrate-comment-style  ·  Safety: format-only
  • Migrate the legacy comment to canonical doc syntax

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-050

Category: LNT (Lint rules)  ·  API stability: stable

deprecated LLM options lint

  • Repair: llm/migrate-deprecated-option  ·  Safety: scope-local
  • Replace the deprecated option with its supported equivalent
  • See also: HARN-LLM-002, HARN-LLM-001

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-051

Category: LNT (Lint rules)  ·  API stability: stable

unnecessary safe navigation lint

  • Repair: expressions/simplify  ·  Safety: behavior-preserving
  • Simplify the expression to its canonical form

navigation)

How to fix

  • Apply the lint's auto-fix where one is offered (harn lint --fix).
  • Suppress the lint with an attribute only when the surrounding code is intentionally non-idiomatic.

HARN-LNT-052

Category: LNT (Lint rules)  ·  API stability: stable

ambient clock builtin replaced by harness.clock.*

  • Repair: bindings/thread-harness-clock  ·  Safety: scope-local
  • Replace the ambient clock builtin with the corresponding harness.clock.* method
  • See also: HARN-NAM-101, HARN-LNT-001

What it means

The lint fires on any call to now_ms, monotonic_ms, sleep_ms, timestamp, or elapsed. These were ambient clock-capability builtins in the pre-Harness runtime. Time access now routes through the harness.clock.* sub-handle so capability requirements appear in the type system instead of being hidden in the stdlib surface.

This is a lint, not a hard error. The legacy builtins still compile while the migration is in flight, but every new call site should use the harness.clock.* method that matches it (now_msharness.clock.now_ms, sleep_msharness.clock.sleep_ms, etc.).

How to fix

  • Run harn fix --apply --safety scope-local over the file. By default the fixer rewrites ambient clock calls to the VM-level harness binding with bindings/use-enclosing-harness-global, preserving helper signatures.
  • If you explicitly want source-level parameter threading, run harn fix --apply --safety surface-changing --harness-threading thread-params. harn fix --plan --json reports which signatures would change and whether cross-module callers must be updated.

HARN-LNT-053

Category: LNT (Lint rules)  ·  API stability: stable

ambient stdio builtin replaced by harness.stdio.*

  • Repair: bindings/thread-harness  ·  Safety: scope-local
  • Thread the existing harness binding through local helper calls and replace the ambient stdio builtin with harness.stdio.*
  • See also: HARN-NAM-101, HARN-LNT-001

What it means

The lint fires on calls to print, println, eprint, eprintln, read_line, and prompt_user. These were ambient stdio-capability builtins in the pre-Harness runtime. Stdio access now routes through the harness.stdio.* sub-handle so capability requirements are visible in the type system.

This lint is emitted during auto-repair planning so existing call sites can be migrated before the removed builtin produces an unknown-name diagnostic. New code should use harness.stdio.print, harness.stdio.println, harness.stdio.eprint, harness.stdio.eprintln, harness.stdio.read_line, or harness.stdio.prompt.

How to fix

  • Run harn fix --apply --safety scope-local over the file. By default the fixer rewrites ambient stdio calls to an existing local Harness binding or to the VM-level harness binding with bindings/use-enclosing-harness-global, preserving helper signatures.
  • If you explicitly want source-level parameter threading, run harn fix --apply --safety surface-changing --harness-threading thread-params. harn fix --plan --json reports which signatures would change and whether cross-module callers must be updated.

HARN-LNT-054

Category: LNT (Lint rules)  ·  API stability: stable

ambient fs builtin replaced by harness.fs.*

  • Repair: bindings/thread-harness-fs  ·  Safety: scope-local
  • Replace the ambient fs builtin with the corresponding harness.fs.* method
  • See also: HARN-NAM-101, HARN-LNT-001

What it means

The lint fires on any call to read_file, write_file, file_exists, delete_file, append_file, list_dir, mkdir, copy_file, temp_dir, mkdtemp, stat, move_file, read_lines, walk_dir, glob, or find_text. These were ambient fs-capability builtins in the pre-Harness runtime. Filesystem access now routes through the harness.fs.* sub-handle so capability requirements appear in the type system instead of being hidden in the stdlib surface.

This is a lint, not a hard error. The legacy builtins still compile while the migration is in flight, but every new call site should use the harness.fs.* method that matches it (read_fileharness.fs.read_text, write_fileharness.fs.write_text, etc.).

How to fix

  • Run harn fix --apply --safety scope-local over the file. By default the fixer rewrites ambient filesystem calls to the VM-level harness binding with bindings/use-enclosing-harness-global, preserving helper signatures.
  • If you explicitly want source-level parameter threading, run harn fix --apply --safety surface-changing --harness-threading thread-params. harn fix --plan --json reports which signatures would change and whether cross-module callers must be updated.

HARN-LNT-055

Category: LNT (Lint rules)  ·  API stability: stable

ambient env builtin replaced by harness.env.*

  • Repair: bindings/thread-harness-env  ·  Safety: scope-local
  • Replace the ambient env builtin with the corresponding harness.env.* method
  • See also: HARN-NAM-101, HARN-LNT-001

What it means

The lint fires on calls to the ambient env and env_or builtins. Environment access now routes through the harness.env.* sub-handle so capability requirements appear in the type system instead of being hidden in the stdlib surface.

This is a lint, not a hard error. The legacy builtins still compile while the migration is in flight, but every new call site should use harness.env.get(name) / harness.env.get_or(name, default).

How to fix

  • Run harn fix --apply --safety scope-local over the file. By default the fixer rewrites ambient env calls to the VM-level harness binding with bindings/use-enclosing-harness-global, preserving helper signatures.
  • If you explicitly want source-level parameter threading, run harn fix --apply --safety surface-changing --harness-threading thread-params. harn fix --plan --json reports which signatures would change and whether cross-module callers must be updated.

HARN-LNT-056

Category: LNT (Lint rules)  ·  API stability: stable

ambient random builtin replaced by harness.random.*

  • Repair: bindings/thread-harness-random  ·  Safety: scope-local
  • Replace the ambient random builtin with the corresponding harness.random.* method
  • See also: HARN-NAM-101, HARN-LNT-001

What it means

The lint fires on calls to the ambient random, random_int, random_choice, and random_shuffle builtins. Randomness now routes through the harness.random.* sub-handle so capability requirements appear in the type system instead of being hidden in the stdlib surface.

This is a lint, not a hard error. The legacy builtins still compile while the migration is in flight, but every new call site should use the matching harness.random.* method (randomharness.random.gen_f64, random_intharness.random.gen_range, etc.). Seeded streams via an explicit Rng handle remain available through the Rng.* surface for tests that need deterministic output.

How to fix

  • Run harn fix --apply --safety scope-local over the file. By default the fixer rewrites ambient random calls to the VM-level harness binding with bindings/use-enclosing-harness-global, preserving helper signatures.
  • If you explicitly want source-level parameter threading, run harn fix --apply --safety surface-changing --harness-threading thread-params. harn fix --plan --json reports which signatures would change and whether cross-module callers must be updated.

HARN-LNT-057

Category: LNT (Lint rules)  ·  API stability: stable

ambient net builtin replaced by harness.net.*

  • Repair: bindings/thread-harness-net  ·  Safety: scope-local
  • Replace the ambient net builtin with the corresponding harness.net.* method
  • See also: HARN-NAM-101, HARN-LNT-001

What it means

The lint fires on calls to the ambient http_get, http_post, http_put, http_patch, http_delete, http_request, and http_download builtins. Outbound HTTP now routes through the harness.net.* sub-handle so capability requirements appear in the type system instead of being hidden in the stdlib surface.

This is a lint, not a hard error. The legacy builtins still compile while the migration is in flight, but every new call site should use the matching harness.net.* method (http_getharness.net.get, http_postharness.net.post, etc.). Streaming, server-mode, and session builtins keep their ambient names today and will migrate in a follow-up ticket.

How to fix

  • Run harn fix --apply --safety scope-local over the file. By default the fixer rewrites ambient network calls to the VM-level harness binding with bindings/use-enclosing-harness-global, preserving helper signatures.
  • If you explicitly want source-level parameter threading, run harn fix --apply --safety surface-changing --harness-threading thread-params. harn fix --plan --json reports which signatures would change and whether cross-module callers must be updated.

HARN-LNT-058

Category: LNT (Lint rules)  ·  API stability: stable

if / while / guard condition is statically known to always succeed or always fail

What it means

The condition of an if, while, or guard is statically known — one of its two branches is unreachable. The lint fires for two patterns:

1. Constant-evaluable conditions

The condition reduces to a known boolean using only literal operands and short-circuit / negation rules. Examples:

  • if true { … }, if false { … } — direct booleans.
  • if nil { … }, if 0 { … }, if "" { … } — falsy literals.
  • if (true || some_call()) { … } — short-circuits to true.
  • if (some_call() && false) { … } — short-circuits to false.
  • if !!true { … } — chains of negations on a constant.

Side-effecting subexpressions inside a vacuous compound (some_call() above) still execute, but their result is dead — usually a mistake left behind by a partial refactor.

2. Statically-determined schema_is / is_type

The variable's static type already proves whether the predicate matches:

  • Always truex's static type is a subtype of the schema, so the truthy branch narrows to nothing new and the falsy branch is dead. Example: x: int and schema_is(x, int), or x: {a: int, b: string} and schema_is(x, {b: string}) (width subtyping).
  • Always falsex's static type and the schema are disjoint. The truthy branch is dead. Example: x: int and schema_is(x, string).

The check is deliberately conservative: it skips when x: unknown or x: any (the open-world top types — schema_is is informative there), and it requires shape fields to match optionality before reporting "always true" (an optional field in x can be absent at runtime, so the predicate may still legitimately fail). The same shape is used by no-unnecessary-condition in typescript-eslint and the unnecessary-invariant rule in Flow.

How to fix

  • If the check is genuinely dead code, remove the surrounding if / while / guard and inline (or delete) the live branch.
  • If you intended a narrower schema, change S to the narrower shape (e.g. a tagged variant, not the parent type).
  • If the variable is meant to come from an untrusted boundary, type it as unknown (or any) and validate at the boundary; the lint will then correctly stay silent.

HARN-LNT-059

Category: LNT (Lint rules)  ·  API stability: stable

project rule-engine or native lint rule

What it means

A project-supplied rule matched here. This is not a built-in lint: it is a structural rule (a *.toml pattern from the project's [rules] ruleDirs) run through the linter via the rule engine (harn-rules), a .lint.harn script rule loaded from ruleDirs, or a trusted native rule library loaded from [rules] nativeRuleDirs.

The message, severity, and any suggested fix come from the matched rule. The diagnostic's reported rule id is the project rule's id, so you filter it with disable_rules (or [lint] config) by that id, exactly like a built-in.

Why it fires

The project declared one or more rule directories:

[rules]
ruleDirs = ["rules"]
nativeRuleDirs = ["native-rules"]

and a rule in one of them matched this code. Declarative rules pair a structural pattern with a message; script rules return findings from lint(source); native rules emit diagnostics through the harn_lint::native ABI. Rules that carry a fix surface it as a machine-applicable lint fix.

How to fix

  • Address the issue the rule describes (see the rule's message).
  • If the rule carries a fix, harn lint --fix applies it. Declarative codemod fixes can also be applied by harn codemod.
  • To silence it, disable the rule by its id, or remove/adjust the rule in your ruleDirs / nativeRuleDirs.

See also

  • The rule engine: harn scan, harn codemod, and the harn-rules skill.
  • Project rule discovery: [rules] ruleDirs and nativeRuleDirs in harn.toml.

HARN-FMT-001

Category: FMT (Formatter)  ·  API stability: stable

formatter could not parse the source

What it means

The formatter could not produce a canonical layout for this source — either because parsing failed first, or because the existing layout drifts from the canonical form.

How to fix

  • Run harn fmt to bring the file to canonical form, or fix the parse error blocking the formatter.

HARN-FMT-002

Category: FMT (Formatter)  ·  API stability: stable

source is not in canonical format

  • Repair: format/reformat  ·  Safety: format-only
  • Apply canonical formatting

What it means

The formatter could not produce a canonical layout for this source — either because parsing failed first, or because the existing layout drifts from the canonical form.

How to fix

  • Run harn fmt to bring the file to canonical form, or fix the parse error blocking the formatter.

HARN-FMT-003

Category: FMT (Formatter)  ·  API stability: stable

formatter normalized trailing comma layout

  • Repair: format/reformat  ·  Safety: format-only
  • Apply canonical formatting

What it means

The formatter could not produce a canonical layout for this source — either because parsing failed first, or because the existing layout drifts from the canonical form.

How to fix

  • Run harn fmt to bring the file to canonical form, or fix the parse error blocking the formatter.

HARN-IMP-001

Category: IMP (Import resolution)  ·  API stability: stable

import target cannot be resolved

  • Repair: imports/fix-path  ·  Safety: scope-local
  • Replace the import path with a resolvable target
  • See also: HARN-MOD-001, HARN-IMP-002

What it means

Import resolution failed at a deeper layer than MOD — the file, symbol, or module graph cannot be constructed. Compilation cannot proceed.

How to fix

  • Add the missing module or symbol, or update the import path.
  • Break import cycles by extracting the shared definitions into a third module.

HARN-IMP-002

Category: IMP (Import resolution)  ·  API stability: stable

imported symbol does not exist

What it means

Import resolution failed at a deeper layer than MOD — the file, symbol, or module graph cannot be constructed. Compilation cannot proceed.

How to fix

  • Add the missing module or symbol, or update the import path.
  • Break import cycles by extracting the shared definitions into a third module.

HARN-IMP-003

Category: IMP (Import resolution)  ·  API stability: stable

import graph contains a cycle

What it means

Import resolution failed at a deeper layer than MOD — the file, symbol, or module graph cannot be constructed. Compilation cannot proceed.

How to fix

  • Add the missing module or symbol, or update the import path.
  • Break import cycles by extracting the shared definitions into a third module.

HARN-OWN-001

Category: OWN (Ownership and mutability)  ·  API stability: stable

immutable binding is reassigned

  • Repair: bindings/make-mutable  ·  Safety: scope-local
  • Mark the binding mut so it can be reassigned
  • See also: HARN-OWN-002

How to fix

  • Switch the binding kind (letmut) to match its actual use.
  • Restructure so owned values do not escape their scope.

HARN-OWN-002

Category: OWN (Ownership and mutability)  ·  API stability: stable

mutable binding is never reassigned

  • Repair: bindings/make-immutable  ·  Safety: behavior-preserving
  • Drop mut since the binding is never reassigned
  • See also: HARN-LNT-018

How to fix

  • Switch the binding kind (letmut) to match its actual use.
  • Restructure so owned values do not escape their scope.

HARN-OWN-003

Category: OWN (Ownership and mutability)  ·  API stability: stable

owned value escapes its valid scope

What it means

A binding annotated with owned<T> carries sole ownership of a drop-able resource (a file, channel, MCP session, transcript writer, sync permit). The compiler emits an implicit defer { drop(x) } at the binding's enclosing block so the resource closes deterministically when control leaves the scope.

Returning the binding by name — or otherwise transferring it out of the scope without declaring the transfer in the type — defeats that contract: the auto- drop never fires, and the resource leaks until the runtime garbage-collects the handle (which, for OS resources, may be never).

fn open_log() -> channel {
  let ch: owned<channel> = channel("log", 64)
  return ch    // HARN-OWN-003: `ch` escapes; auto-drop is bypassed
}

How to fix

  • Transfer ownership explicitly by declaring the function's return type as owned<T>. The caller then receives an owned binding and is responsible for dropping it (or transferring it on again):

    fn open_log() -> owned<channel> {
      let ch: owned<channel> = channel("log", 64)
      return ch    // OK — ownership flows to the caller
    }
    
  • Drop the value before returning by wrapping the work in a block whose exit triggers the auto-drop, then returning a non-owned summary:

    fn write_log(msg: string) -> nil {
      {
        let ch: owned<channel> = channel("log", 64)
        send(ch, msg)
      }   // `ch` drops here, before the function returns
      nil
    }
    
  • Drop the value explicitly with drop(x) if you need to release earlier than the enclosing block would close it.

HARN-OWN-004

Category: OWN (Ownership and mutability)  ·  API stability: stable

unvalidated boundary value is used directly

How to fix

  • Switch the binding kind (letmut) to match its actual use.
  • Restructure so owned values do not escape their scope.

HARN-RCV-001

Category: RCV (Error recovery)  ·  API stability: stable

rescue construct is outside a function body

  • Repair: errors/wrap-in-fn  ·  Safety: surface-changing
  • Move the construct inside a function body
  • See also: HARN-RCV-002, HARN-RCV-003

What it means

A recovery construct (try, rescue) is in an invalid position or is shaped in a way Harn's structured-error handling does not support.

How to fix

  • Move the construct inside a function body, or wrap it in one.
  • Use try / rescue only around expressions that can produce structured errors.

HARN-RCV-002

Category: RCV (Error recovery)  ·  API stability: stable

try construct is outside a function body

  • Repair: errors/wrap-in-fn  ·  Safety: surface-changing
  • Move the construct inside a function body
  • See also: HARN-RCV-001

What it means

A recovery construct (try, rescue) is in an invalid position or is shaped in a way Harn's structured-error handling does not support.

How to fix

  • Move the construct inside a function body, or wrap it in one.
  • Use try / rescue only around expressions that can produce structured errors.

HARN-RCV-003

Category: RCV (Error recovery)  ·  API stability: stable

rescue construct is invalid

What it means

A recovery construct (try, rescue) is in an invalid position or is shaped in a way Harn's structured-error handling does not support.

How to fix

  • Move the construct inside a function body, or wrap it in one.
  • Use try / rescue only around expressions that can produce structured errors.

HARN-MAT-001

Category: MAT (Match exhaustiveness)  ·  API stability: stable

match expression is not exhaustive

  • Repair: match/add-missing-arms  ·  Safety: scope-local
  • Add arms covering the missing variants
  • See also: HARN-MAT-003, HARN-MAT-002

What it means

A match expression is incomplete, ambiguous, or otherwise invalid. Harn enforces exhaustive matching to keep agent decision logic auditable.

How to fix

  • Add arms covering the remaining variants, or use a wildcard _ arm as the explicit fallback.
  • Remove duplicate arms — each variant should appear at most once.

HARN-MAT-002

Category: MAT (Match exhaustiveness)  ·  API stability: stable

match expression contains a duplicate arm

  • Repair: match/remove-duplicate-arm  ·  Safety: behavior-preserving
  • Remove the duplicated match arm
  • See also: HARN-MAT-001, HARN-LNT-037

What it means

A match expression is incomplete, ambiguous, or otherwise invalid. Harn enforces exhaustive matching to keep agent decision logic auditable.

How to fix

  • Add arms covering the remaining variants, or use a wildcard _ arm as the explicit fallback.
  • Remove duplicate arms — each variant should appear at most once.

HARN-MAT-003

Category: MAT (Match exhaustiveness)  ·  API stability: stable

match pattern is invalid

What it means

A match expression is incomplete, ambiguous, or otherwise invalid. Harn enforces exhaustive matching to keep agent decision logic auditable.

How to fix

  • Add arms covering the remaining variants, or use a wildcard _ arm as the explicit fallback.
  • Remove duplicate arms — each variant should appear at most once.

HARN-POL-001

Category: POL (Runtime policies)  ·  API stability: stable

pool backpressure rejected a submit

pool.submit(...) attempted to enqueue work into a bounded pool whose backpressure policy was already full and configured with on_full: "fail_submitter".

Increase the queue depth, choose a different on_full policy, wait for existing task handles to drain, or catch the error and retry from your own orchestration policy.

HARN-POL-002

Category: POL (Runtime policies)  ·  API stability: stable

fail-fast pool has no immediate capacity

pool.submit(...) targeted a pool configured with Backpressure().fail_fast, but all worker slots were already occupied. Fail-fast pools do not queue work.

Catch the error if rejection is expected, raise max_concurrent, or use Backpressure().queue(...) when callers should wait, drop, or retain a bounded queue instead.

HARN-MET-001

Category: MET (Compile-time meta restrictions)  ·  API stability: stable

expression is not permitted in a const initializer

What it means

A const binding's right-hand side must be a pure expression that can be folded at compile time by the bounded const-evaluator. The expression referenced something the evaluator does not permit: a call into a non-const function, a property access on a host object such as harness, a runtime construct (spawn / parallel / select / try / yield / emit / await), a loop, an assignment, or any builtin outside the curated const-friendly allowlist.

Rejected:

const Z = harness.clock.now()              // host capability
const W = spawn { 1 }                      // runtime construct
const Q = some_user_fn()                   // user function call

Accepted:

const X: int = 5 + 3
const Y: string = format("hello-{}", X)
const NS: list = [1, 2, X]
const COUNT: int = len([1, 2, 3])

// reads to silence the unused-variable lint in the example
let _ = [X, Y, NS, COUNT]

How to fix

  • Move the side-effecting computation into a regular let binding inside a pipeline or function body.
  • If the value really is a compile-time constant, restructure it as arithmetic, string concatenation, literal collections, or reads of earlier const bindings.

Stability

Adding pure builtins to the const-eval allowlist is backwards-compatible — newly permitted expressions stop being rejected.

HARN-CST-001

Category: CST (Const-eval sandbox)  ·  API stability: stable

const initializer exceeded the step budget

What it means

The bounded compile-time evaluator counts every reduction step it performs while folding a const initializer. When the running count exceeds MAX_STEPS (default 100,000), evaluation is aborted with this diagnostic. The cap is enforced on every step, not amortized, so a hostile or accidental quadratic expression cannot stall the compiler.

// Rejected (would expand far beyond the step budget):
const HUGE = sum_to(1_000_000)

How to fix

  • Pre-compute the value off-line and embed a literal.
  • Reduce the expression to a smaller closed form.
  • If the work genuinely belongs at runtime, switch from const to let.

Stability

The default budget may grow over time; tightening it would require a deprecation cycle.

HARN-CST-002

Category: CST (Const-eval sandbox)  ·  API stability: stable

const initializer exceeded the recursion depth budget

What it means

The compile-time evaluator tracks how deeply it has recursed into nested expressions or conditionals. Exceeding MAX_DEPTH (default 256) aborts evaluation with this diagnostic. The cap protects the compiler thread's stack and prevents pathological deeply-nested literals from creating an unbounded stack frame chain.

How to fix

  • Flatten deeply-nested literals (e.g. a 1,000-level nested ternary).
  • Break the constant into intermediate const bindings.

Stability

The default budget may grow over time; tightening it would require a deprecation cycle.

HARN-CST-003

Category: CST (Const-eval sandbox)  ·  API stability: stable

const initializer attempted a sandboxed capability

What it means

The compile-time evaluator denies any expression that would touch the filesystem, network, environment, the current process, host bindings (harness.*), the orchestration runtime, or any other ambient side effect. Even a syntactically reachable call into one of those surfaces is rejected before evaluation runs — the const-eval sandbox refuses to mediate I/O or non-determinism.

// Rejected:
const X = read_file("/etc/passwd")
const Y = env("HOME")
const Z = spawn { ... }
const W = harness.clock.now()

How to fix

  • Move the impure expression into a let binding inside a pipeline.
  • Replace I/O with a literal value or with a pure transformation of already-folded constants.

Stability

The denylist is enforced by allowlist (only listed pure builtins are accepted), so newly added stdlib functions stay sandboxed by default.

HARN-CST-004

Category: CST (Const-eval sandbox)  ·  API stability: stable

const initializer raised a runtime error during evaluation

What it means

The expression was syntactically eligible for compile-time evaluation, but the evaluator hit a value-level error during folding: integer overflow on a literal arithmetic, division by zero, indexing past the end of a literal list, an undefined identifier the const-eval environment cannot resolve, or a type mismatch on a binary operator.

// Rejected at compile time:
const ZERO = 1 / 0
const OOB = [1, 2, 3][9]
const BAD = "a" + 1

How to fix

  • Inspect the offending operand and supply a valid value.
  • If the expression depends on a value that is only known at runtime, use let instead of const.

HARN-CMP-001

Category: CMP (Bytecode compilation)  ·  API stability: stable

the program failed to compile to bytecode

The program parsed and type-checked, but the bytecode compiler rejected it. These are structural or codegen errors the type checker does not model yet — for example an unsupported nested list/dict pattern in a match arm, a break or continue outside a loop, try* outside a function, or a malformed string interpolation hole.

harn check runs this compilation pass (discarding the bytecode) so that any error which would stop harn run is reported up front, rather than only when the program is executed.

How to fix

  • Read the message: it names the specific construct the compiler could not lower and usually how to rewrite it.
  • For nested match patterns, bind the element with an identifier and match it in a nested match.
  • For break/continue, ensure they appear inside a loop.