Sakura Lang

V2031 not_show

A value whose type is not Show was interpolated or printed.

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

A value whose type is not Show was interpolated or printed. Secret<T> is never Show, so secrets cannot leak into strings or logs (design §6.4).

Wrong:

Log.event(Level.Info, "token {token}", [])

Fixed:

Log.event(Level.Info, "token set", [])

Wrong program

compiler/tests/ui/V2031_secret_interpolated.sakura, which the compiler's ui suite runs through sakura check:

fn leak() -> Unit ! {Env, Log} {
  let token = Env.secret("BILLING_TOKEN").expect("BILLING_TOKEN")
  Log.event(Level.Info, "token {token}", [])
}

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

{
  "schema_version": "1.0",
  "kind": "diagnostic",
  "id": "d:1db993c328ef9123",
  "code": "V2031",
  "severity": "error",
  "phase": "type",
  "message": "`Secret<String>` is not `Show`, so it cannot be interpolated or printed; secrets cannot be shown, pass them to a sink such as `Http.bearer`",
  "snapshot": "sha256:$SNAPSHOT",
  "symbol_id": "main::V2031_secret_interpolated::leak",
  "spans": [
    {
      "uri": "file://$DIR/V2031_secret_interpolated.sakura",
      "content_hash": "sha256:577018d20ab792123d30ea7aebba44ae2d4bfe1e9fdaaeba92b4edc94cf3a140",
      "start_byte": 165,
      "end_byte": 170,
      "role": "primary"
    }
  ],
  "related_ids": [],
  "expected": {
    "render": "Show"
  },
  "actual": {
    "render": "Secret<String>"
  },
  "obligation": null,
  "counterexample": null,
  "explanation_uri": "sakura://explain/V2031",
  "fixes": []
}

Fixed program

compiler/tests/ui/V2031_secret_interpolated.fixed.sakura, which sakura check accepts with no diagnostics:

fn leak() -> Unit ! {Env, Log} {
  let _token = Env.secret("BILLING_TOKEN").expect("BILLING_TOKEN")
  Log.event(Level.Info, "token set", [])
}
Edit on GitHub

On this page