# V2015 error_union_annotation_needed

URL: /docs/errors/V2015
Markdown: /docs/errors/V2015.md

> Two different error unions meet in synthesis mode (for example the branches of an if).

An error from the `type` phase. `sakura explain V2015` prints this explanation offline.

Two different error unions meet in synthesis mode (for example the branches of an `if`).
Annotate the binding or function with the union you mean (design §5.3).

## Wrong program [#wrong-program]

[`compiler/tests/ui/V2015_error_union_annotation_needed.sakura`](https://github.com/icantcodefyi/sakuralang/blob/master/compiler/tests/ui/V2015_error_union_annotation_needed.sakura), which the compiler's ui suite runs through `sakura check`:

```sakura
error A

error B

fn fa() -> Int ! {Fail<A>} { fail A }

fn fb() -> Int ! {Fail<B>} { fail B }

fn pick(c: Bool) -> Unit { let _ = if c { try { fa() } } else { try { fb() } } }
```

`sakura check --json` reports this record (pretty-printed; `$DIR` is the fixture's directory):

```json
{
  "schema_version": "1.0",
  "kind": "diagnostic",
  "id": "d:2d029aebf6a3e91f",
  "code": "V2015",
  "severity": "error",
  "phase": "type",
  "message": "expected `Result<Int, A>`, found `Result<Int, B>` (`B` is not `A`); annotate the binding with the joined error union",
  "snapshot": "sha256:$SNAPSHOT",
  "symbol_id": "main::V2015_error_union_annotation_needed::pick",
  "spans": [
    {
      "uri": "file://$DIR/V2015_error_union_annotation_needed.sakura",
      "content_hash": "sha256:2407ddc115dd635ed4832eb5bb83ac5ccdbf144d1035f9a18519a101d334e3e8",
      "start_byte": 192,
      "end_byte": 208,
      "role": "primary",
      "label": "this has type `Result<Int, B>`"
    }
  ],
  "related_ids": [],
  "expected": {
    "render": "Result<Int, A>"
  },
  "actual": {
    "render": "Result<Int, B>"
  },
  "obligation": null,
  "counterexample": null,
  "explanation_uri": "sakura://explain/V2015",
  "fixes": []
}
```

## Fixed program [#fixed-program]

[`compiler/tests/ui/V2015_error_union_annotation_needed.fixed.sakura`](https://github.com/icantcodefyi/sakuralang/blob/master/compiler/tests/ui/V2015_error_union_annotation_needed.fixed.sakura), which `sakura check` accepts with no diagnostics:

```sakura
error A

error B

fn fa() -> Int ! {Fail<A>} { fail A }

fn fb() -> Int ! {Fail<B>} { fail B }

fn pick(c: Bool) -> Unit { let _: Result<Int, A | B> = if c { try { fa() } } else { try { fb() } } }
```
