# exceptions

URL: /kida/api/exceptions/
Section: api
Description: Exceptions for Kida template system.

Standalone module with zero internal imports at module level,
breaking the deepest circular import chain (environment → exceptions → environment).

Exception Hierarchy:
TemplateError (base)
├── TemplateNotFoundError     # Template not found by loader
├── TemplateSyntaxError       # Parse-time syntax error
├── TemplateRuntimeError      # Render-time error with context
│   ├── RequiredValueError    # Required value was None/missing
│   └── NoneComparisonError   # Attempted None comparison (sorting)
└── UndefinedError            # Undefined variable access

Error Messages:
All exceptions provide rich error messages with:
- Source location (template name, line number)
- Expression context where error occurred
- Actual values and their types
- Source snippets showing the offending template line
- Actionable suggestions for fixing

Example:
    ```
    UndefinedError: Undefined variable 'titl' in article.html:5
       |
     5 | <h1>{{ titl }}</h1>
       |
    Hint: Did you mean 'title'? Or use {{ titl | default('') }}
    ```

---

> For a complete page index, fetch /kida/llms.txt.

Open LLM text
(/kida/api/exceptions/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fexceptions%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fexceptions%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fexceptions%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fexceptions%2Findex.txt)

Module

#
`exceptions`

Exceptions for Kida template system.

Standalone module with zero internal imports at module level,
breaking the deepest circular import chain (environment → exceptions → environment).

Exception Hierarchy:

TemplateError (base)
├── TemplateNotFoundError # Template not found by loader
├── TemplateSyntaxError # Parse-time syntax error
├── TemplateRuntimeError # Render-time error with context
│ ├── RequiredValueError # Required value was None/missing
│ └── NoneComparisonError # Attempted None comparison (sorting)
└── UndefinedError # Undefined variable access

Error Messages:

All exceptions provide rich error messages with:

- Source location (template name, line number)

- Expression context where error occurred

- Actual values and their types

- Source snippets showing the offending template line

- Actionable suggestions for fixing

Example:

```
```
UndefinedError: Undefined variable 'titl' in article.html:5
|
5 | <h1>{{ titl }}</h1>
|
Hint: Did you mean 'title'? Or use {{ titl | default('') }}
```
```

18Classes4Functions

## Classes

`ErrorCode`

2

▼

Searchable error codes for Kida template errors.

Format: K-{CATEGORY}-{NUMBER}
Categories: LEX (le…

Searchable error codes for Kida template errors.

Format: K-{CATEGORY}-{NUMBER}
Categories: LEX (lexer), PAR (parser), RUN (runtime), TPL (template loading)

Each code maps to a documentation URL for quick lookup:
https://lbliii.github.io/kida/docs/errors/#k-run-001

#### Methods

`docs_url`

0

`str`

▼

Documentation URL for this error code.

property

`def docs_url(self) -> str`

##### Returns

`str`

`category`

0

`str`

▼

Error category (e.g., 'runtime', 'lexer', 'parser', 'template', 'security').

property

`def category(self) -> str`

##### Returns

`str`

`TemplateWarning`

6

▼

Compile-time template warning (not an exception).

Compile-time template warning (not an exception).

#### Attributes

Name
Type
Description

`code`

`ErrorCode`

—

`message`

`str`

—

`template_name`

`str | None`

—

`lineno`

`int | None`

—

`suggestion`

`str | None`

—

#### Methods

`format_message`

0

`str`

▼

Format warning for display.

`def format_message(self) -> str`

##### Returns

`str`

`KidaWarning`

0

▼

Base warning category for Kida template warnings.

Base warning category for Kida template warnings.

`PrecedenceWarning`

0

▼

Operator precedence may cause unexpected results.

Operator precedence may cause unexpected results.

`CoercionWarning`

0

▼

Implicit type coercion in filter.

Implicit type coercion in filter.

`MigrationWarning`

0

▼

Jinja2 migration: behavior differs from Jinja2.

Jinja2 migration: behavior differs from Jinja2.

`ComponentWarning`

0

▼

Component contract validation warning.

Component contract validation warning.

`SourceSnippet`

4

▼

Template source context around an error line.

Provides surrounding lines of template source for di…

Template source context around an error line.

Provides surrounding lines of template source for display in error
messages. Used by TemplateRuntimeError and UndefinedError to show
the template line where the error occurred.

#### Attributes

Name
Type
Description

`lines`

`tuple[tuple[int, str], ...]`

Tuple of (line_number, line_content) pairs around the error.

`error_line`

`int`

The 1-based line number where the error occurred.

`column`

`int | None`

Optional column offset for caret pointer.

#### Methods

`format`

0

`str`

▼

Format snippet in Rust-inspired diagnostic style with colors.

Returns a multi-…

`def format(self) -> str`

Format snippet in Rust-inspired diagnostic style with colors.

Returns a multi-line string with line numbers and the error line
highlighted. Uses terminal colors when supported.

##### Returns

`str`

`DiagnosticLocation`

5

▼

Surface-neutral template location for exception renderers.

Surface-neutral template location for exception renderers.

#### Attributes

Name
Type
Description

`template`

`str`

—

`line`

`int | None`

—

`column`

`int | None`

—

`filename`

`str | None`

—

#### Methods

`format`

0

`str`

▼

Return ``template[:line[:column]]`` without terminal styling.

`def format(self) -> str`

##### Returns

`str`

`DiagnosticFrame`

4

▼

Surface-neutral stack frame for template/component diagnostics.

Surface-neutral stack frame for template/component diagnostics.

#### Attributes

Name
Type
Description

`template`

`str`

—

`line`

`int`

—

`name`

`str | None`

—

#### Methods

`format`

0

`str`

▼

Return a plain frame label.

`def format(self) -> str`

##### Returns

`str`

`TemplateDiagnostic`

16

▼

Structured diagnostic data for downstream renderers.

This payload intentionally stores plain strin…

Structured diagnostic data for downstream renderers.

This payload intentionally stores plain strings and immutable tuples only.
HTML, markdown, and terminal escaping/styling belongs to the renderer that
consumes it.

#### Attributes

Name
Type
Description

`code`

`str | None`

—

`title`

`str`

—

`message`

`str`

—

`kind`

`str`

—

`location`

`DiagnosticLocation`

—

`source_snippet`

`SourceSnippet | None`

—

`hints`

`tuple[str, ...]`

—

`docs_url`

`str | None`

—

`suggestion`

`str | None`

—

`template_stack`

`tuple[DiagnosticFrame, ...]`

—

`component_stack`

`tuple[DiagnosticFrame, ...]`

—

`metadata`

`tuple[tuple[str, str], ...]`

—

#### Methods

`metadata_dict`

0

`dict[str, str]`

▼

Return metadata as a regular dict for consumers that prefer mapping APIs.

`def metadata_dict(self) -> dict[str, str]`

##### Returns

`dict[str, str]`

`format_html_fragment`

0

`str`

▼

Render a dependency-free escaped HTML diagnostic fragment.

This is intentional…

`def format_html_fragment(self) -> str`

Render a dependency-free escaped HTML diagnostic fragment.

This is intentionally compact and unstyled so framework debug pages can
wrap it in their own chrome without inheriting terminal formatting.

##### Returns

`str`

`format_html_page`

1

`str`

▼

Render a standalone escaped HTML diagnostic page.

`def format_html_page(self, *, page_title: str = 'Kida Template Error') -> str`

##### Parameters

Name
Type
Description

`page_title`
`—`

Default:`'Kida Template Error'`

##### Returns

`str`

`format_markdown`

0

`str`

▼

Render a GitHub-flavored Markdown diagnostic from plain fields.

`def format_markdown(self) -> str`

##### Returns

`str`

`TemplateError`

2

▼

Base exception for all Kida template errors.

All template-related exceptions inherit from this cla…

Base exception for all Kida template errors.

All template-related exceptions inherit from this class, enabling
broad exception handling:

```
>>> try:
...     template.render()
... except TemplateError as e:
...     log.error(f"Template error: {e}")
```

#### Attributes

Name
Type
Description

`code`

`ErrorCode | None`

Optional ErrorCode for searchable, documentable error identification.

#### Methods

`format_compact`

0

`str`

▼

Format error as a structured, human-readable summary.

Produces a clean diagnos…

`def format_compact(self) -> str`

Format error as a structured, human-readable summary.

Produces a clean diagnostic string suitable for terminal display,
without Python traceback noise. Consumers (Chirp, Bengal) can call
this instead of parsing`str(exc)`.

Format::

```
K-RUN-001: Undefined variable 'usernme' in base.html:42
   |
>42 | <h1>{{ usernme }}</h1>
   |
Hint: Use {{ usernme | default('') }} for optional variables
Docs: https://lbliii.github.io/kida/docs/errors/#k-run-001
```

##### Returns

`str`

Multi-line string with error code, message, source snippet,
and documentation URL.

`TemplateNotFoundError`

1

▼

Template not found by any configured loader.

Raised when `Environment.get_template(name)` cannot l…

Template not found by any configured loader.

Raised when`Environment.get_template(name)`cannot locate the template
in any of the loader's search paths.

#### Attributes

Name
Type
Description

`code`

`ErrorCode | None`

—

`TemplateSyntaxError`

3

▼

Parse-time syntax error in template source.

Raised by the Parser when template syntax is invalid. …

Parse-time syntax error in template source.

Raised by the Parser when template syntax is invalid. Includes source
location for error reporting.

When`source` and `lineno`are provided, the error message includes
a source snippet with the offending line. If`col_offset`is also
given, a caret (`^`) points at the exact column.

#### Attributes

Name
Type
Description

`code`

`ErrorCode | None`

—

#### Methods

`format_compact`

0

`str`

▼

Format syntax error as structured terminal diagnostic.

`def format_compact(self) -> str`

##### Returns

`str`

Internal Methods
1

▼

`__init__`

6

▼

`def __init__(self, message: str, lineno: int | None = None, name: str | None = None, filename: str | None = None, source: str | None = None, col_offset: int | None = None)`

##### Parameters

Name
Type
Description

`message`
`—`

`lineno`
`—`

Default:`None`

`name`
`—`

Default:`None`

`filename`
`—`

Default:`None`

`source`
`—`

Default:`None`

`col_offset`
`—`

Default:`None`

`TemplateRuntimeError`

9

▼

Render-time error with rich debugging context.

Raised during template rendering when an operation …

Render-time error with rich debugging context.

Raised during template rendering when an operation fails. Provides
detailed information to help diagnose the issue:

- Template name and line number

- The expression that caused the error

- Actual values and their types

- Actionable suggestion for fixing

Output Format:

```
        Runtime Error: 'NoneType' object has no attribute 'title'
          Location: article.html:15
          Expression: {{ post.title }}
          Values:
            post = None (NoneType)
          Suggestion: Check if 'post' is defined, or use {{ post.title | default('') }}
```
```






#### Attributes




        Name
        Type
        Description





        `code`

              `ErrorCode | None`



  —





  `message`

  —




Error description






  `expression`

  —




Template expression that failed






  `values`

  —




Dict of variable names → values for context






  `template_name`

  —




Name of the template






  `lineno`

  —




Line number in template source






  `suggestion`

  —




Actionable fix suggestion











#### Methods

















        `format_compact`

0


          `str`


▼


Format runtime error as structured terminal diagnostic.









      `def format_compact(self) -> str`




##### Returns

      `str`











      Internal Methods
      1

    ▼













        `__init__`

10

▼










      `def __init__(self, message: str, *, expression: str | None = None, values: dict[str, Any] | None = None, template_name: str | None = None, lineno: int | None = None, suggestion: str | None = None, source_snippet: SourceSnippet | None = None, template_stack: list[tuple[str, int]] | None = None, component_stack: list[tuple[str, int, str]] | None = None, code: ErrorCode | None = None)`




##### Parameters




        Name
        Type
        Description





        `message`
`—`






  `expression`
`—`


  Default:`None`





  `values`
`—`


  Default:`None`





  `template_name`
`—`


  Default:`None`





  `lineno`
`—`


  Default:`None`





  `suggestion`
`—`


  Default:`None`





  `source_snippet`
`—`


  Default:`None`





  `template_stack`
`—`


  Default:`None`





  `component_stack`
`—`


  Default:`None`





  `code`
`—`


  Default:`None`






























        `RequiredValueError`

2

▼


A required value was None or missing.

Raised by the `| require` filter when a value that must be p…










A required value was None or missing.


Raised by the`| require`filter when a value that must be present is
None or missing. Useful for validating required context variables.






#### Attributes




        Name
        Type
        Description





        `code`

              `ErrorCode | None`



  —










#### Methods








          Internal Methods
          1

        ▼













        `__init__`

3

▼










      `def __init__(self, field_name: str, message: str | None = None, **kwargs: Any)`




##### Parameters




        Name
        Type
        Description





        `field_name`
`—`






  `message`
`—`


  Default:`None`





  `**kwargs`
`—`































        `NoneComparisonError`

2

▼


Attempted to compare None values, typically during sorting.

Raised when `| sort` or similar operat…










Attempted to compare None values, typically during sorting.


Raised when`| sort`or similar operations encounter None values that
cannot be compared. Provides information about which items have None
values for the sort attribute.






#### Attributes




        Name
        Type
        Description





        `code`

              `ErrorCode | None`



  —










#### Methods








          Internal Methods
          1

        ▼













        `__init__`

4

▼










      `def __init__(self, left_value: Any, right_value: Any, attribute: str | None = None, **kwargs: Any)`




##### Parameters




        Name
        Type
        Description





        `left_value`
`—`






  `right_value`
`—`






  `attribute`
`—`


  Default:`None`





  `**kwargs`
`—`































        `UndefinedError`

8

▼


Raised when accessing an undefined variable.

Strict mode is enabled by default in Kida. When a tem…










Raised when accessing an undefined variable.


Strict mode is enabled by default in Kida. When a template references
    a variable that doesn't exist in the context, this error is raised
    instead of silently returning None.


If`available_names`is provided, a "Did you mean?" suggestion is
included when a close match is found (using`difflib.get_close_matches`).

To fix:



- Pass the variable in render(): template.render(undefined_var="value")


- Use the default filter: {{ undefined_var | default("fallback") }}







#### Attributes




        Name
        Type
        Description





        `code`

              `ErrorCode | None`



  —










#### Methods

















        `diagnostic_hints`

0


          `tuple[str, ...]`


▼


Return ordered plain-text hints for structured renderers.









      `def diagnostic_hints(self) -> tuple[str, ...]`




##### Returns

      `tuple[str, ...]`















        `to_diagnostic`

0


          `TemplateDiagnostic`


▼


Return a surface-neutral diagnostic payload for this error.









      `def to_diagnostic(self) -> TemplateDiagnostic`




##### Returns

      `TemplateDiagnostic`















        `format_compact`

0


          `str`


▼


Format undefined variable error as structured terminal diagnostic.









      `def format_compact(self) -> str`




##### Returns

      `str`











      Internal Methods
      4

    ▼













        `__init__`

9

▼










      `def __init__(self, name: str, template: str | None = None, lineno: int | None = None, available_names: frozenset[str] | None = None, source_snippet: SourceSnippet | None = None, template_stack: list[tuple[str, int]] | None = None, component_stack: list[tuple[str, int, str]] | None = None, kind: str = 'variable', declared_definitions: frozenset[str] | None = None)`




##### Parameters




        Name
        Type
        Description





        `name`
`—`






  `template`
`—`


  Default:`None`





  `lineno`
`—`


  Default:`None`





  `available_names`
`—`


  Default:`None`





  `source_snippet`
`—`


  Default:`None`





  `template_stack`
`—`


  Default:`None`





  `component_stack`
`—`


  Default:`None`





  `kind`
`—`


  Default:`'variable'`





  `declared_definitions`
`—`


  Default:`None`




















        `_closest_available_name`

0


          `str | None`


▼


Return the best fuzzy match from available names, if any.









      `def _closest_available_name(self) -> str | None`




##### Returns

      `str | None`















        `_hint_text`

0


          `str`


▼


Return the hint line shown after the error message.

When the missing name matc…









      `def _hint_text(self) -> str`




Return the hint line shown after the error message.


When the missing name matches a known top-level definition, point
  the user at the declaration site instead of suggesting`default`,
because no default value will work — the name is meant to resolve
to a {% region %} or {% def %} that is not yet bound at this point
in the render (typically because it is declared but unreachable
at module-init time, or render_block was called for the wrong
block).






##### Returns

      `str`















        `_nullsafe_hint_text`

0


          `str | None`


▼


Return an additional null-safe hint for attribute/key errors.

For missing attr…









      `def _nullsafe_hint_text(self) -> str | None`




Return an additional null-safe hint for attribute/key errors.


For missing attributes or dict keys under strict mode, the fix is
  usually to switch the access to a null-safe form rather than to
  supply a default at the variable level. Since v0.8.0,`?.`and
`?[...]` on Mapping receivers return `None`for missing keys —
so`x?.y`alone is the fix for dict-key misses; object-attr misses
still need`?? ""` or the `get`filter.






##### Returns

      `str | None`




















## Functions











        `_terminal`

0

▼


Lazy import of terminal color utilities (avoids circular imports).









      `def _terminal()`














        `format_template_stack`

1


          `str`


▼


Format template call stack for error messages with colors.









      `def format_template_stack(stack: list[tuple[str, int]] | None) -> str`




##### Parameters




        Name
        Type
        Description





        `stack`
`list[tuple[str, int]] | None`


List of (template_name, line_number) tuples showing include chain











##### Returns

      `str`















        `format_component_stack`

1


          `str`


▼


Format component call stack for error messages with colors.









      `def format_component_stack(stack: list[tuple[str, int, str]] | None) -> str`




##### Parameters




        Name
        Type
        Description





        `stack`
`list[tuple[str, int, str]] | None`


List of (template_name, line_number, def_name) tuples showing the def call chain.











##### Returns

      `str`















        `build_source_snippet`

4


          `SourceSnippet`


▼


Build a SourceSnippet from template source.









      `def build_source_snippet(source: str, error_line: int, *, context_lines: int = 2, column: int | None = None) -> SourceSnippet`




##### Parameters




        Name
        Type
        Description





        `source`
`str`


Full template source text.






  `error_line`
`int`


1-based line number of the error.






  `context_lines`
`int`


Number of lines to show before/after the error line.


  Default:`2`





  `column`
`int | None`


Optional column offset for caret pointer.


  Default:`None`










##### Returns

      `SourceSnippet`
