harn-parser 0.10.163

Parser, AST, and type checker for the Harn programming language
Documentation
# HARN-LNT-080 - `?.` chain over an untyped value

## What it means

A chain of two or more `?.` links reads fields from a value whose type the
checker does not know: `any`, `unknown`, an open `dict`, or a value with no
inferred type. Parsed JSON, command output decoded by hand, and responses
passed around as `dict` all look like this:

```harn,ignore
const pr = response.data?.repository?.pullRequest
const head = to_string(pr?.headRefOid ?? "")
```

Every link hedges against a shape nobody declared. A misspelled field reads as
`nil` and falls through to the default, so the code runs and reports nothing.

The rule fires once per chain, on its second optional link. A chain over a
typed record whose fields are declared optional is real nil handling and is
not reported. The finding is advisory (`info`): existing code still carries
thousands of these chains, so it does not fail `harn lint --strict`.

## How to fix

Declare the shape you rely on and decode the value once, where it enters. When
the value is your own data passed around as `dict`, annotate the parameter or
return type that erased it instead.

```harn
type PullRequest = {headRefOid: string, isDraft: bool, mergedAt: string?}
type Snapshot = {repository: {pullRequest: PullRequest?}}

fn head_of(raw: unknown) -> Result<string, string> {
  match schema_parse(raw, schema_of(Snapshot)) {
    Result.Err(error) -> {
      return Err(error.message)
    }
    Result.Ok(snapshot) -> {
      const pr = snapshot.repository.pullRequest
      if pr == nil {
        return Err("pull request not found")
      }
      return Ok(pr.headRefOid)
    }
  }
}
```

`schema_parse` returns `Result<T, SchemaError>`, so a function that returns a
`Result` can write `schema_parse(raw, schema_of(Snapshot))?` instead. Unknown
fields pass validation. A field written `name: T?` must be present but may be
`null`; `name?: T` may also be absent.

See "Decode at the boundary" in the error-handling guide.