Quick Reference

This page lists every frontmatter key, Lua global and member, substitution form, default and limit, and error kind in the prompt language, each linked to the chapter that teaches it. Use it to look up an exact form or value, and follow the link when you need to know how that piece behaves.

Frontmatter keys

Every frontmatter key and value rule, with top-level keys first and nested keys grouped under their parent.

KeyValueDefaultTaught in
Top-level key setname, description, promptforge, max_tool_iterations, input, output, plugins, tools, args, modelsonly name and description requiredPrompt File Structure
namestring, kept as writtennone, requiredPrompt File Structure
descriptionone-line string, kept as writtennone, requiredPrompt File Structure
promptforge0none, needed to runPrompt File Structure
max_tool_iterationswhole number 1 to 100024 per models.loop call, or the Harness's defaultConversations
inputmap of path and descriptionno input filePrompt File Structure
outputmap of path and descriptionno output filePrompt File Structure
pluginslist of Plugin entriesno PluginsTools
toolsmap of alias to tool pathno tool slotsTools
argsmap of arg name to arg declarationimplicit prose argArguments
modelsmap of role label to role declarationno model rolesModels
args.{name}arg declaration mapnoneArguments
args.{name}.defaultvalue matching typeno defaultArguments
args.{name}.descriptionstringno descriptionArguments
args.{name}.optionalbooleanfalseArguments
args.{name}.typestring, boolean, integer, or numbernone, requiredArguments
Implicit prose argoptional string arg prose, described as Freeform input for this promptused when args is absentArguments
input.descriptionstringnone, requiredPrompt File Structure
input.pathstore filename, such as paper.mdnone, requiredPrompt File Structure
models.{label}role declaration map, {} for nonenoneModels
models.{label}.descriptionstringthe bound model's catalog descriptionModels
models.{label}.keywordslist drawn from the seven keywords, kept in orderno keywordsModels
models.{label}.keywords entry chatsoft keywordnot setModels
models.{label}.keywords entry creativesoft keywordnot setModels
models.{label}.keywords entry fastsoft keywordnot setModels
models.{label}.keywords entry frontiersoft keywordnot setModels
models.{label}.keywords entry no-thinkinghard keyword, thinking offnot setModels
models.{label}.keywords entry smallsoft keywordnot setModels
models.{label}.keywords entry thinkinghard keyword, thinking onnot setModels
models.{label}.min_contextwhole number of tokens, 1 to 4294967295no minimumModels
Name grammar for aliases, role labels, and arg names[A-Za-z][A-Za-z0-9_-]{0,63}nonePrompt File Structure
output.descriptionstringnone, requiredPrompt File Structure
output.pathstore filename, such as report.mdnone, requiredPrompt File Structure
plugins entry as a stringPlugin id namespace/plugin, such as promptforge/webrequired, no configTools
plugins entry configany YAML valueno configTools
plugins entry optionalbooleanfalseTools
plugins entry refPlugin idnone, required in the map formTools
Reserved names for tool aliases and role labelsno Engine global, sandbox Lua global, or Lua keyword, such as store, argv, pairs, or end, and no name under both tools and models; the chapter lists every onenonePrompt File Structure
Tool path in tools.{alias}namespace/plugin/name, such as promptforge/web/fetchnoneTools
tools.{alias}tool path stringnoneTools

Lua globals and members

Every global, function, field, and record shape a prompt's Lua code can use, with its form, what it gives back, and the chapter that teaches it.

models

NameFormReturnsTaught in
handle.capabilitiesh.capabilitiesThe role's keywords, a sequence of kebab-case strings in declaration orderModels
handle.contexth.contextThe bound model's context window in tokens, at least 1Models
handle.descriptionh.descriptionThe role's description:, or the model's catalog description, which can be emptyModels
handle.labelh.labelThe role label, the same string as h.nameModels
handle.max_tokensh.max_tokensThe max_tokens option from models.use, or nilModels
handle.model_idh.model_idThe bound model's catalog id, such as claude-sonnet-4-6Models
handle.nameh.nameThe role labelModels
handle.temperatureh.temperatureThe temperature option from models.use, or nilModels
handle.thinkingh.thinkingtrue for thinking, false for no-thinking, nil for neitherModels
model handlelocal h = models.get('writer')Frozen userdata with nine read-only fields and no methodsModels
models.defaultmodels.default(label)The default role's model handle; sets the prompt-wide defaultModels
models.getmodels.get(label)The role's model handle; the selection is unchangedModels
models.getmodels.get(ui().selected_model)A model handle for a Host catalog model id, with a Host-state snapshot onlyModels
models.infermodels.infer(prompt)The reply as a string, from one round on the section's modelModels
models.infermodels.infer(handle, prompt)The reply as a string, from one round on the handle's modelModels
models.loopmodels.loop(messages, compactor?)nil; appends every record to messagesConversations
models.loopmodels.loop(handle, messages, compactor?)nil; every round runs on the handle's modelConversations
models.loop compactor argumentmodels.loop(msgs, function(reason) ... end)Called with "precheck" or "provider" on overflowConversations
models.usemodels.use(label)The role's model handle; selects the role for the sectionModels
models.use option max_tokens{ max_tokens = n }Whole number from 1 to 4294967295; read back as h.max_tokensModels
models.use option temperature{ temperature = n }Finite number from 0.0 to 2.0; read back as h.temperatureModels
models.use optionsmodels.use(label, { temperature = 0.3, max_tokens = 256 })A model handle carrying the options; an omitted option reads nilModels

messages

NameFormReturnsTaught in
builder chainingmessages.new():system(s):user(u)The same list, one record appended per call in call orderConversations
content part image_url{ type = "image_url", image_url = { url = "data:image/png;base64,..." } }An image part in a record's content arrayConversations
content part text{ type = "text", text = "..." }A text part in a record's content arrayConversations
list:appendlist:append(record)The same list, with record appended unchangedConversations
list:assistantlist:assistant(content, tool_calls?)The same list, with an assistant record appendedConversations
list:systemlist:system(content)The same list, with { role = "system", content = content } appendedConversations
list:toollist:tool(content, tool_call_id)The same list, with a tool record appendedConversations
list:userlist:user(content)The same list, with { role = "user", content = content } appendedConversations
messages.newmessages.new()An empty message list, length 0Conversations
record.contentrecord.contentA string, or a non-empty array of content partsConversations
record.rolerecord.rolesystem, user, assistant, or toolConversations
record.tool_call_idrecord.tool_call_idOn a tool record, the string id of the call it answersConversations
record.tool_callsrecord.tool_callsOn an assistant record, an array of { id, name, arguments? }Conversations
tool call entrycall.id, call.name, call.argumentsThe call id, the alias the model called, and the parsed arguments tableConversations

compactors

NameFormReturnsTaught in
compactors.failmodels.loop(msgs, compactors.fail)The default policy; an overflowing round raises context_exhaustedConversations
compactors.fail(tag)compactors.fail('precheck')Never returns; raises context_exhausted with reason set to the tagConversations
overflow reason "precheck"err.reason == 'precheck'The request's token count plus the room kept for the reply exceeded the context window; nothing was sentConversations
overflow reason "provider"err.reason == 'provider'The provider rejected the request as too large for the context windowConversations

tools

NameFormReturnsTaught in
Tool objectthe alias global, such as searchA frozen Tool object with five fields and no methodsTools
Tool.descriptionsearch.descriptionThe tool's catalog description, never an overrideTools
Tool.namesearch.nameThe alias the slot is bound underTools
Tool.parameterssearch.parametersAn empty tableTools
Tool.untrustedsearch.untrustedfalseTools
Tool.wire_namesearch.wire_nameThe last segment of the tool path, such as fetchTools
tools.addtools.add(alias_or_tool)Nothing; scopes the tool into the current sectionTools
tools.add array formtools.add({ 'search', fetch })Nothing; scopes every listed toolTools
tools.add description overridetools.add(alias, description)Nothing; sets the model's description for this sectionTools
tools.add_localtools.add_local(alias, description, params, handler)Nothing; registers a local tool in the sectionTools
tools.add_local handler argsfunction(a) return a.text endOne fresh table of the call's arguments, by declared nameTools
tools.add_local handler returnreturn 'saved'A scalar, as the call's text; nil gives the empty stringTools
tools.add_local param types"string", "integer", "number", "boolean"The parameter's JSON Schema typeTools
tools.add_local params table{ query = 'string', limit = { 'integer', 'maximum hits' } }JSON Schema object parameters, every one requiredTools
tools.allow_taskstools.allow_tasks()Nothing; scopes the task built-ins, allowing any section the chain can resolveTasks
tools.allow_tasks targets listtools.allow_tasks({ '## Summarize', '## Review' })Nothing; scopes the task built-ins and limits the model's task calls to the listed headingsTasks
tools.alwaystools.always(alias)Nothing; scopes the tool into every sectionTools
tools.always description overridetools.always(alias, description)Nothing; sets the model's description for the whole runTools
tools.calltools.call(alias_or_tool, args?)The tool's output: a string, or a table from a structured toolTools
tools.callstools.calls[alias] or tools.calls.aliasThe section's call count for that alias, an integerTools

store

NameFormReturnsTaught in
store.appendstore.append(path, contents)nil; adds contents to the end, creating the file when absentThe Store
store.deletestore.delete(path)nil; removes the file or an empty directory, and succeeds when absentThe Store
store.existsstore.exists(path)true or false, for a file or a directoryThe Store
store.globstore.glob(pattern)A sorted array of matching store file paths, or only directories for a pattern ending in /The Store
store.readstore.read(path)The whole file verbatim as a stringThe Store
store.read with a rangestore.read(path, start, end?)Lines start to end, 1-based and inclusive, joined with "\n"The Store
store.read_numberedstore.read_numbered(path)The whole file as N| text lines numbered from 1The Store
store.read_numbered with a rangestore.read_numbered(path, start, end?)The selected lines with their absolute line numbersThe Store
store.str_replacestore.str_replace(path, old, new)nil; replaces the single occurrence of old with newThe Store
store.writestore.write(path, contents)nil; creates the file or replaces its textThe Store

tasks

NameFormReturnsTaught in
Task handle{ task = id }A plain methodless table; the bare id string also worksTasks
tasks.canceltasks.cancel(task)Nothing; cancelling an ended task does nothingTasks
tasks.notetasks.note(text)Nothing; sets the note field of tasks.statusTasks
tasks.pendingtasks.pending(filter?)The chain's live Task handles in spawn order, empty when noneTasks
tasks.pending filter origintasks.pending({ origin = 'model' })Only live tasks of that origin, author or modelTasks
tasks.readytasks.ready(task)true once the task has ended, else falseTasks
tasks.spawntasks.spawn(target, opts?)A Task handle, at onceTasks
tasks.spawn option index{ index = n }The task's sys.index, an integer of 0 or moreTasks
tasks.spawn option input{ input = s }A string that replaces the task's argsTasks
tasks.spawn option item{ item = v }JSON data that becomes the task's itemTasks
tasks.statustasks.status(task)The status table of an owned task or of sys.taskidTasks
tasks.status fieldstasks.status(t).statetarget, origin, state, ok, section, blocked, turns, tasks, depth, noteTasks
tasks.concurrencytasks.concurrency(n?)The chain's effective admission limit, lowered by n, clamped to the parent'sTasks
tasks.jointasks.join(set, opts?)A results sequence in set order, then timed_outTasks
tasks.join result entryresults[i]{ task, ok, result }, itself a Task handleTasks
tasks.join timed_outlocal results, timed_out = tasks.join(set, { timeout = 5 })true when the timeout expired first, else falseTasks
tasks.join_anytasks.join_any(set, opts?)The ended member's Task handle, ok, and its result text or error valueTasks
tasks.join_any with a timeouttasks.join_any(set, { timeout = 5 })nil when no member ended in timeTasks
wait option timeout{ timeout = seconds }A whole, fractional, or zero number of secondsTasks

sys

NameFormReturnsTaught in
sys.executionsys.executionThe run's name, assigned by the HarnessThe Lua Environment
sys.idsys.idThe current section entry's id, such as 0.3.0The Lua Environment
sys.indexsys.indexAn arm's 1-based position in its collection, or a task's index optionFanout
sys.modelsys.modelThe section's catalog model id, readable only after the section's first tool callModels
sys.section_countsys.section_countThe number of top-level sections in the promptThe Lua Environment
sys.section_namesys.section_nameThe running section's heading name, or the title in the H1 passThe Lua Environment
sys.taskidsys.taskidThe nearest enclosing task's id, 0 on the main walkThe Lua Environment
sys.whensys.whenThe run's start instant as an RFC 3339 stringThe Lua Environment

Model-facing task tools

For each tool and argument, Form is what the model sends and Returns is the text the model gets back; the tools.allow_tasks row is the Lua call that puts these tools in scope.

NameFormReturnsTaught in
await_tasks{}Every task notice that has arrived, one per line, once one of the model's tasks ends; nothing to wait for when none is runningTasks
await_tasks.timeout{"timeout": 0.1}Any notices, then timed out; tasks {ids} still running when no task ended in time; slept {seconds} seconds when none is runningTasks
task{"target": "## Research"}Task id={id} started, at onceTasks
task.input"input": "text", optionalReplaces the task's argument stringTasks
task.target"target": "## Research", requiredNames the section the task runsTasks
task_cancel{"id": "0.0"}Task id={task} cancelledTasks
task_cancel.id"id": "0.0", requiredNames a task the model started, exactly as task returned itTasks
task_status{"id": "0.0"}One line starting Task id={task} (## {target}): {state}Tasks
task_status.id"id": "0.0", requiredNames a task the model started, exactly as task returned itTasks
tools.allow_taskstools.allow_tasks(targets?) in Luatask, task_cancel, task_status, and await_tasks in scope for every round in the sectionTasks

Web tools

For each tool and argument, Form is what the model sends and Returns is the text the model gets back; the promptforge/web row is the Plugin line that makes the tools available.

NameFormReturnsTaught in
promptforge/webplugins: [promptforge/web]The tool paths promptforge/web/fetch and promptforge/web/searchWeb Fetch and Search
promptforge/web/fetch{"url": "https://example.com/"}A url:, truncated:, extraction: header, a blank line, then the content, in the untrusted envelopeWeb Fetch and Search
promptforge/web/fetch max_chars"max_chars": 5000, optionalAt most that many characters, 1 to the policy's limit (40,000 by default); the limit when omittedWeb Fetch and Search
promptforge/web/fetch raw"raw": true, optionalThe whole HTML page as markdown, with extraction: raw-html; false when omittedWeb Fetch and Search
promptforge/web/fetch url"url": "https://example.com/", requiredThe page at that addressWeb Fetch and Search
promptforge/web/search{"query": "rust async runtime"}JSON text with a results array, in the untrusted envelopeWeb Fetch and Search
promptforge/web/search count"count": 5, optionalAt most that many results, 1 to 20; the gateway's default when omittedWeb Fetch and Search
promptforge/web/search country"country": "us", optionalOne country's results; 1 to 128 characters, not blankWeb Fetch and Search
promptforge/web/search exclude_domains"exclude_domains": ["example.com"], optionalDrops results from those sites; at most 20 bare hostnamesWeb Fetch and Search
promptforge/web/search freshness"freshness": "pw", optionalResults from the past day, week, month, or year: pd, pw, pm, or pyWeb Fetch and Search
promptforge/web/search include_domains"include_domains": ["example.com"], optionalOnly results from those sites; at most 20 bare hostnamesWeb Fetch and Search
promptforge/web/search query"query": "rust async runtime", requiredThe search text; 1 to 400 characters, not blankWeb Fetch and Search
promptforge/web/search safesearch"safesearch": "strict", optionalThe SafeSearch level: off, moderate, or strictWeb Fetch and Search
promptforge/web/search search_lang"search_lang": "en", optionalThe search language; 1 to 128 characters, not blankWeb Fetch and Search

Operator input

The promptforge/user-input row is the Plugin line that defines the rest. The two input rows are Lua calls, and the ask tool row is what a model sends when the prompt lets it ask.

NameFormReturnsTaught in
promptforge/user-inputplugins: [promptforge/user-input]The input global and the tool path promptforge/user-input/ask; required, the run is refused when the Host has nobody to askThe Lua Environment
input.asklocal text, available = input.ask() in Luathe operator's next message and true, or the fixed fallback sentence and falseThe Lua Environment
input.connectedinput.connected() in Luatrue when the Host has someone to ask; fixed for the whole runThe Lua Environment
promptforge/user-input/ask{}The operator's next message, trusted; offered to a model only through a tools: aliasThe Lua Environment

Lua standard library

Every section VM runs Lua 5.5 with these libraries and base functions.

NameFormReturnsTaught in
_G_Gthe global tableThe Lua Environment
_VERSION_VERSIONthe Lua version stringThe Lua Environment
assertassert(condition, message)raises message when condition is falseThe Lua Environment
errorerror(message)raises messageThe Lua Environment
getmetatablegetmetatable(v)as in standard Lua 5.5; var and sys give a guard string, and _G gives the metatable you set or nilThe Lua Environment
ipairsipairs(t)as in standard Lua 5.5The Lua Environment
math librarymath.{name}(...)as in standard Lua 5.5The Lua Environment
selectselect(n, ...)as in standard Lua 5.5The Lua Environment
setmetatablesetmetatable(t, mt)t; on _G, mt composes behind the argv and prose guardThe Lua Environment
string librarystring.upper(s), s:match(pattern)as in standard Lua 5.5The Lua Environment
table librarytable.{name}(...)as in standard Lua 5.5The Lua Environment
table.concattable.concat(list, sep, i, j)joined string; __tostring values render with tostringThe Lua Environment
tonumbertonumber(v)as in standard Lua 5.5The Lua Environment
tostringtostring(v)string; an error value gives its messageThe Lua Environment
typetype(v)type name; an error value gives 'table'The Lua Environment

Other globals

These globals, fanout result fields, and error value fields need no declaration.

NameFormReturnsTaught in
{alias}{alias}Tool object for that bound tool slot; never a reserved nameTools
argsargsthe raw argument stringArguments
argvargvthe parsed argument string; { prose = args } without args:, nil when structured input is not JSONArguments
callcall(target, input?)the called chain's result as a stringJump and Call
compactorscompactors.failthe compactors namespaceConversations
err .. s and s .. err'prefix: ' .. errconcatenation with the error's messageThe Lua Environment
err.finish_reasonerr.finish_reasonprovider finish reason on empty_model_reply, when sentConversations
err.kind and err.messagelocal ok, err = pcall(f, ...)error kind tag; message stringThe Lua Environment
err.kind tagserr.kind == '{tag}'one of exactly thirteen tagsThe Lua Environment
err.nameerr.namerequested tool name on unbound_tool and out_of_scope_toolTools
err.reasonerr.reasonprecheck or provider on context_exhausted; a store reason such as not_found, invalid_path, or anchor on storeConversations
err.taskerr.tasktask id on task_not_owned, task_consumed, and a cancelled taskTasks
err.taskserr.tasksleaked task ids joined with , in spawn order, on tasks_liveTasks
fanoutfanout(worker, collection)array of fanout results, one per member in collection orderFanout
heading reference'## Name'the section with that level and nameJump and Call
Engine globalsno importinstalled in every section VMThe Lua Environment
itemitemthe arm's member inside a fanout arm, or a task's item optionFanout
item.key and item.valueitem.key, item.valuea keyed member's key and valueFanout
jumpjump(target)nothing; ends the block and the walk continues at targetJump and Call
{label}{label}model handle for that bound role; never a reserved nameModels
list_from_sectionlist_from_section(heading)1-based array of the list section's item stringsBlocks and Prose
loglog(message)nothing; records a lua checkpoint eventThe Lua Environment
messagesmessages.new()the messages namespaceConversations
modelsmodels.{name}(...)the models namespaceModels
nextnext(t, k?)next key and value in pairs order; nil, nil past the last keyThe Lua Environment
pairspairs(t)iteration in the same fixed key order on every runThe Lua Environment
pcallpcall(f, ...)true and results, or false and an error value or the value you raisedThe Lua Environment
proseprosethe block's pending prose, rendered, as a stringBlocks and Prose
result.exhaustedr[i].exhaustedtrue only when the arm's models.loop hit the round capFanout
result.itemr[i].itemthe member the arm processedFanout
result.okr[i].oktrue when the arm completed normally, false at the round capFanout
result.textr[i].textthe arm's result text, '' when it returned noneFanout
storestore.{name}(...)the store namespaceThe Store
syssys.{field}the sys namespaceThe Lua Environment
taskstasks.{name}(...)the tasks namespaceTasks
toolstools.{name}(...)the tools namespaceTools
tostring(err)tostring(err)the error's message, with no tracebackThe Lua Environment
tostring(result) and table.concat(results)tostring(r[i]), table.concat(r, sep)the result's text; the joined textsFanout
uiui()Host-state snapshot table; present only when the Host supplies oneThe Lua Environment
untrusteduntrusted(s)s inside an untrusted envelopeThe Store
varvar.key = valueyour own values, carried along the walkThe Lua Environment
xpcallxpcall(f, handler, ...)like pcall; handler receives the error valueThe Lua Environment

Substitution forms

Each row links to the section that teaches the form.

FormRendersTaught in
Inserted textVerbatim, never scanned againSubstitution
Resolved valueStrings as is, numbers and booleans in natural form, tables and arrays as compact JSON with sorted keysSubstitution
\{{, \}}, \\{{, }}, \Substitution
{{ args }}The argument string exactly as passedSubstitution
{{ argv }}The whole parsed argumentsSubstitution
{{ argv.key }}One field of the parsed arguments, at any depthSubstitution
{{ item }}The seeded item of a fanout arm or a task, by its type, JSON null as nullSubstitution
{{ name }}A section-local Lua global, wholeSubstitution
{{ name.key }}A field of a table held in a Lua globalSubstitution
{{ path }}The value its first segment names: args, argv, item, var, sys, or a Lua globalSubstitution
{{ sys.key }}A runtime-provided sys fieldSubstitution
{{ var.key }}A value in var, with dotted paths for nested fieldsSubstitution

Defaults and limits

Set by names the frontmatter key that sets a value, or says whether the Harness sets it or it is fixed.

NameDefaultRange or ruleSet byTaught in
Call depth cap8 levelsNested call, fanout arms, and tasks share it, first call includedfixedJump and Call
Cancel poll interval10,000 instructionsA Host cancel stops a running block within this many instructionsfixedLimits and Errors
Concurrency limit8 tasks at onceEvery task the run admits, fanout arms included; tasks.concurrency lowers it for a chain's own spawnsHarnessFanout
Generic completion textdoneThe run result when no block returns a scalarfixedHow a Prompt Runs
Harness-set limitsListed in the chapterA prompt changes only the round capHarnessLimits and Errors
Instruction countNo capOnly the cancel poll counts instructionsfixedLimits and Errors
Log byte quota262,144 bytes per section VM256 UTF-8 bytes per allowed log event, so it follows the log event quotaHarnessLimits and Errors
Log event quota1024 log calls per section VMEvery one-argument log call spends oneHarnessLimits and Errors
Log message length256 charactersCounted as Unicode charactersfixedThe Lua Environment
Lua memory64 MiB per section VMRunning out is an ordinary lua errorHarnessLimits and Errors
Model receive timeout120 secondsApplies to the headers and to each next body chunkHarnessLimits and Errors
Model response cap16 MiBA larger reply fails the callHarnessLimits and Errors
Round cap default24 roundsPer models.loop call, when max_tool_iterations is absentHarnessConversations
Round cap from frontmatterThe Harness defaultWhole number 1 to 1000, per models.loop callmax_tool_iterationsConversations
Run limit defaultsListed in the chapterOne set applies to the whole runHarnessLimits and Errors
input.ask fallback sentenceUser input is unavailable in this host; continue without it.Returned with available set to false when the Host has nobody to askfixedThe Lua Environment

Error kinds

Parse error kinds classify a file that fails to parse, run error kinds classify how a failed run ended, and error kinds on error values are the kind tags a pcall sees.

Parse error kinds

KindRaised whenMessage namesTaught in
FenceA second lua shared fence, a lua shared fence outside the H1, or an unclosed fenceThe unclosed fence's label or section name, else nothingLimits and Errors
FrontmatterThe frontmatter block is missing, unclosed, or not valid YAML, or a frontmatter key or value is rejectedThe YAML diagnostic, in invalid frontmatter: {message}, or the rejected key's own message, with the line and column beside itLimits and Errors
ListA list section holds non-list content, an empty item, or no itemsThe section name, and the offending line for non-list contentLimits and Errors
LuaA Lua region (the shared library, an H1 block, or a section block) does not compileThe section and block, plus the compiler diagnosticLimits and Errors
StructureThe H1 title is missing, repeated, or empty, a heading is empty or has no parent one level up, two siblings share a name, or the file has no promptforge: key when runThe section name, the heading level, and both lines of a duplicate siblingLimits and Errors

Run error kinds

KindRaised whenMessage namesTaught in
BindingA section sends prose to a model or calls models.infer without a handle while no models.use or models.default is in effectThe section, in model binding required for section {section}Limits and Errors
Cancelled outcomeThe Host cancels the run, or a caught cancelled error value is raised again after another suspending call; a clean stop with no run error kind, not a failureNothing; the outcome carries no messageLimits and Errors
CompletionA model call fails at the transport, backend, or decode layer (a disabled gateway included), or an empty reply, and the error goes uncaughtThe failure's fixed phrase, with the backend status when there is oneLimits and Errors
ContextExhaustedA round overflows the model's context window under the selected compactor and goes uncaughtThe reason, in context exhausted: {reason}Limits and Errors
DeterminismTwo accesses unordered by happens-before touch one store region in conflicting ways; the call never returns, so no pcall catches it, not even during a shared library loadThe store path, both chains, and both claim kinds, in store determinism violation: {detail}Limits and Errors
InternalAn Engine invariant breaks, a fault in the Engine rather than the promptThe invariant, in internal invariant violated: {message}Limits and Errors
LuaAn uncaught Lua failure in a walked section, call chain, task, fanout arm, or the shared library load, including a failed substitution, running out of memory, and a block that returns a table; a task error in any chain; a caught lua, internal, out_of_scope_tool, unbound_tool, or task error value raised again after another suspending callThe Lua error's own textLimits and Errors
ParseThe file fails with any parse error kind, or has no promptforge: keyThe parse error's own message, with its location beside it when knownLimits and Errors
QuotaThe log event quota or the log byte quota runs out and the error goes uncaughtNothing, as in lua log event quota exceeded or lua log byte quota exceededLimits and Errors
RequirementsUnmetPrepare finds a required Plugin missing, two declared Plugins in conflict, or a model role requirement unmet, or an ordinary Lua error goes uncaught in the H1 passEach unmet requirement on its own line, or the Lua error textLimits and Errors
Retryable failuresCompletion failures from a transport failure (a receive timeout included), a malformed or oversized reply, a rate limit or an overloaded backend, or a backend status of 500 or higher; nothing reruns a failed run automaticallyThe backend status, when there is oneLimits and Errors
VfsAn uncaught store failure, a caught one raised again, a run whose handle declares no store, or the Host's store backend failing outside any store callThe store failure's own text, as in file not found in store: {path} or store operation failedLimits and Errors
ToolA tool fails, the model calls a tool outside the round's scope, a script calls an alias not bound in the run, or models.loop reaches its round cap, and the error goes uncaughtThe tool's failure text, the requested name and the aliases in scope or bound, or nothing, as in tool-call loop did not convergeLimits and Errors
VersionThe promptforge: key declares a major version other than 0The declared version, in unsupported promptforge version: {n} (this build supports major 0)Limits and Errors

Error kinds on error values

KindRaised whenMessage namesTaught in
cancelledA Host cancel reaches running Lua or a waiting call, or a wait returns it, unraised, for a cancelled taskNothing, as in interrupted by Ctrl-C, or the task, in task `{task}` was cancelled; field taskLimits and Errors
context_exhaustedA models.loop round overflows the context window under compactors.fail, or a script calls compactors.fail(tag)The reason in words, in context exhausted: {reason}; field reason is "precheck" or "provider"Conversations
empty_model_replyA models.loop reply is empty and is not the clean exitThe message the model replied with no text and no tool calls; field finish_reason when the provider sent oneConversations
internalA failure outside the prompt: a model call's transport, backend, or decode failure, a disabled gateway, the missing-model error, or an Engine faultThe failure's fixed phrase with the backend status when there is one, or the section, depending on the failureLimits and Errors
luaA runtime error, an Engine call's argument or misuse error, running out of memory, a spent log quota, or a failed substitutionThe error's own text, such as the unknown field or the store pathLimits and Errors
storeA store call fails, except a claims conflict, which ends the run as Determinism without raisingThe store's message, as in file not found in store: {path}; field reason, plus path, and anchor and count or ruleThe Store
out_of_scope_toolThe model calls a name outside the round's scopeThe requested name and the aliases in scope, in tool "{name}" is not in this section's scope; in-scope aliases: [...]; field nameTools
task_consumedA wait names a task already deliveredThe task, in task `{task}` was already delivered: a task's result is taken by one wait; field taskTasks
task_not_ownedA wait, status read, or cancel names a task the chain does not own, or an id that names no taskThe task, in task `{task}` is not a task this chain owns; field taskTasks
tasks_liveA chain ends normally with tasks it spawned still liveThe leaked ids in spawn order; field tasks, joined with , Tasks
toolA bound tool fails in a script tools.callThe tool's model-safe failure text, in tool call failure: {message}Tools
tool_loop_exhaustedmodels.loop makes its round cap of rounds without a final replyNothing, as in tool-call loop did not convergeConversations
unbound_toolA script tools.call names neither a local tool nor an alias bound in the run, or names a task built-inThe name and every bound alias, in tool "{name}" is not bound in this run; bound aliases: [...]; field nameTools