Error Reference
Every error norq emits, grouped by phase.
Resolve Errors
Errors that occur when norq locates and loads project files.
norq.config.yaml not found
Cause: No config file exists in the current directory or any parent.
Fix: Run norq init to create a project, or cd into an existing norq project.
Failed to read config: {message}
Cause: The config file exists but cannot be parsed (invalid YAML, bad types, etc.).
Fix: Open norq.config.yaml and fix the syntax error described in {message}.
Notifications directory not found: {path}
Cause: The directory specified by the notifications key in config does not exist.
Fix: Create the directory, or update the notifications path in norq.config.yaml.
Notification '{id}' not found at {path}
Cause: A notification was requested by ID but no matching directory with channel files exists at the expected path.
Fix: Check the notification ID for typos. Ensure the directory contains at least one channel file (e.g., email.md, sms.md).
Both {id}.md and {id}.json exist. Use one format per channel.
Cause: A channel has both a Markdown and a JSON template file in the same notification directory.
Fix: Delete one of the two files. Each channel uses exactly one format.
IO error: {message}
Cause: A filesystem operation failed (permission denied, disk full, broken symlink, etc.).
Fix: Address the OS-level issue described in {message}.
Invalid entry '{name}' in notifications directory. Only 'system/', 'transactional/', 'promotional/', and directories starting with '_' are allowed at the root level.
Cause: A directory or file at the root of notifications/ does not match an allowed notification type or shared directory prefix.
Fix: Move the entry into system/, transactional/, or promotional/. Shared directories must start with _ (e.g., _partials/).
Invalid notification type '{name}'. The first segment of a notification ID must be one of: system, transactional, promotional.
Cause: A notification ID begins with an unrecognized type segment.
Fix: Rename the parent directory to system, transactional, or promotional.
Parse Errors
Errors that occur when norq parses template files.
Unclosed directive '{name}' starting at line {line}
Cause: A block directive (:::if, :::each, etc.) was opened but never closed with :::.
Fix: Add the closing ::: on its own line after the block content.
:::else without matching :::if at line {line}
Cause: A :::else directive appears outside any :::if block.
Fix: Remove the stray :::else, or add the missing :::if before it.
Unexpected closing directive at line {line}
Cause: A closing ::: appears without a matching opening directive.
Fix: Remove the extra :::, or add the missing opening directive.
Unclosed frontmatter block
Cause: The opening --- frontmatter fence has no matching closing ---.
Fix: Add a closing --- line after the frontmatter YAML.
Invalid frontmatter: {message}
Cause: The YAML between the --- fences is malformed or contains invalid keys/values.
Fix: Fix the YAML syntax error described in {message}.
Invalid expression at line {line}: {message}
Cause: A {{ }} expression contains syntax norq cannot parse (unclosed braces, invalid identifiers, etc.).
Fix: Correct the expression syntax at the indicated line.
Invalid condition at line {line}: {message}
Cause: The condition inside a :::if directive is malformed.
Fix: Rewrite the condition using valid norq expression syntax.
Compile Errors
Errors that occur when norq compiles templates into channel-native payloads.
Compilation error for {channel}: {message}
Cause: A channel-specific compiler failed (missing required frontmatter, unsupported syntax, data type mismatch, etc.).
Fix: Read {message} for the specific issue and fix the {channel} template accordingly.
MJML rendering error: {message}
Cause: The generated MJML for an email template is invalid and the MJML-to-HTML renderer rejected it.
Fix: This usually indicates a bug in norq's email compiler. File an issue with the template that triggered it.
Provider Errors
Errors that occur when norq delivers compiled payloads via providers.
Unknown provider: {name}
Cause: The provider name in config or send() call does not match any built-in or registered provider.
Fix: Check spelling. Available providers are listed in the providers: section of norq.config.yaml.
Provider '{provider}' error: {message}
Cause: The provider accepted the request but the upstream API returned an error (auth failure, rate limit, invalid recipient, etc.).
Fix: Read {message} for the provider-specific error. Check credentials and recipient data.
No provider configured for channel '{channel}'
Cause: A send() call targets a channel that has no provider mapping in norq.config.yaml.
Fix: Add a provider for the channel under the providers key in norq.config.yaml.
Lint Warnings
Warnings reported by norq lint. These are non-blocking but indicate real problems.
template/undefined-variable
Cause: An expression references a variable not found in data.schema.yaml.
Fix: Add the variable to your schema, or fix the typo in the expression.
template/nullable-access
Cause: A variable that is not in required is used without a null guard.
Fix: Wrap in ::: if variable ... ::: or use | default "fallback".
template/inline-directive
Cause: A ::: appears mid-line instead of at the start of its own line.
Fix: Move the ::: to the beginning of a new line. Directives are block-level — inline ::: is rendered as literal text.
template/directive-in-table
Cause: A directive (::: if, ::: each, etc.) appears between table rows.
Fix: Tables and directives cannot be mixed. Use a list with ::: each or ::: fields with Key: Value lines instead.
template/table-in-fields
Cause: A Markdown table appears inside a ::: fields directive.
Fix: Use Key: Value paragraph lines instead of a table. Example:
::: fields
Order ID: {{order.id}}
Status: {{order.status}}
:::
template/thematic-break
Cause: A --- line appears after frontmatter. In Markdown this renders as a horizontal rule (<hr>).
Fix: Use *** if you want a horizontal rule, or remove the line if it was unintended.
template/raw-expression
Cause: An unescaped triple-brace expression {{{ }}} is used.
Fix: Ensure the value is trusted (no user-generated HTML). Prefer double-brace {{ }} with auto-escaping.