---
# System prepended metadata

title: Error Message Reformat
tags: [schema]

---

---
title: "Error Message Reformat"
tags: "schema"
---


:::danger
:boom: **Do Not Edit This Document**

The work described in here is now living in:

https://github.com/vmware-tanzu/carvel-ytt/issues/396
:::

# Error Message Reformat

Inspired by: https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-come.html

General desired improvements:
- more important information is in a more prominent place
    1. what is the error? — the source line where the error likely occurred
    2. what's wrong? — the exact expectation/invariant that was broken
    3. where abouts? — roughly where about within the source file (i.e. line number)
    4. where _exactly_? — the name of the file
    5. how can I fix it? — hints of what to do next
- make clear what's literal source and what's commentary.

## General Improvements
- keep source line dead center (where the eye typically goes first) with even more surrounding whitespace
- split filename and line number
  - reduce required eye movement to locate source line
  - makes output display more predictable (left-side is _always_ 8 characters wide)
- use `=` in the gutter to indicate line is commentary, not source
- bring description of actual and expected as just below the source line (where eye goes next)
- ALL CAPS reads like yelling; instead pull error message to the top-line (relatively low prominence) to get proper separation from other data.
- whitespace to separate "expectations" and "hints"
- allow for multiple hints (e.g. split on `\n`?) to be able to provide more than one piece of advice without it getting too complicated.
- use the verb "define" (instead of "declare") consistently throughout error messages.

## Scenarios

- [Invalid Schema](#Invalid-Schema)
- [Invalid Array Definition](#Invalid-Array-Definition)
- [Mismatched Type](#MismatchediType)
- [Undefined Map Key](#Undefined-Map-Key)

### Invalid Schema

`null` provided as a value in Schema (which is both useless and likely a misguided attempt at making the default value `null` — when the author _should_ use `@schema/nullable`)

                       
**Before**
```
ytt: Error:
values/00-values.yml:4 | system_domain:
                       |
                       | INVALID SCHEMA - null value is not allowed in schema (no type can be inferred from it)
                       |   (hint: to default to null, specify a value of the desired type and annotate with @schema/nullable)
```

**After**

```
ytt: Error: Invalid schema — null value not allowed here

 values/00-values.yml:
       |
     4 | system_domain:
       |
       = found: null value
       = expected: non-null value
       =
       = hint: in YAML, omitting a value implies null.
       = hint: to set the default value to null, annotate with @schema/nullable.
       = hint: to allow any value, annotate with @schema/type any=True.
```


### Invalid Array Definition


**Before**
```
ytt: Error:
values/00-values.yml:7 | app_domains: []
                       |
                       | INVALID ARRAY DEFINITION IN SCHEMA - unable to determine the desired type
                       |      found: 0 array items
                       |   expected: exactly 1 array item, of the desired type
                       |   (hint: in a schema, the item of an array defines the type of its elements; its default value is an empty list)
```                    

**After**
```
ytt: Error: Invalid schema — wrong number of items in array definition

  values/00-values.yml:
       |
     7 | app_domains: []
       |
       = found: 0 array items
       = expected: exactly 1 array item, of the desired type
       =
       = hint: in schema, the one item of the array implies the type of its elements.
       = hint: in schema, the default value for an array is always an empty list.
       = hint: default values can be overriden via a data values overlay.
```

### Mismatched Type

```
ytt: Error: Overlaying data values (in following order: values.yml):
values.yml:3 | foo: ""
             |
             | TYPE MISMATCH - the value of this item is not what schema expected:
             |      found: string
             |   expected: integer (by schema.yml:3)
```

**After**
```
ytt: Error: Value is of wrong type

  values.yml:
       |
     3 | foo: ""
       |
       = found: string
       = expected: integer (by schema.yml:3)
```

### Undefined Map Key

**Before**
```
ytt: Error: Overlaying data values (in following order: values/10-images.yml, values/20-secrets-config-values.yml, values/30-experimental-values.yml, cf-values.yml):
values/10-images.yml:4 | images:
                       |
                       | UNEXPECTED KEY - the key of this item was not found in the schema's corresponding map:
                       |      found: images
                       |   expected: (a key defined in map) (by values/00-values.yml:2)
                       |   (hint: declare data values in schema and override them in a data values document)
```

**After**
```
ytt: Error: Overlaying data values (in following order: values/10-images.yml, values/20-secrets-config-values.yml, values/30-experimental-values.yml, cf-values.yml): 
  Undefined key in map:

  values/10-images.yml:
       |
     4 | images:
       |
       = found: images
       = expected: (a key from the map defined at values/00-values.yml:2)
       =
       = hint: is the key spelled correctly?
       = hint: to extend existing schema, define new keys in a schema overlay.
```
