# Attributes


The `attributes` object on an [error report](/docs/protocol/errors/payload) is a flat map holding everything Flare knows about the error. [Resource](/docs/protocol/general/resources) and [scope](/docs/protocol/general/resources#scope) attributes get merged into the same object.

This page covers what a browser client puts there. For the Laravel, database and job attributes a PHP client sends, see [Attributes](/docs/protocol/errors/attributes) in the PHP protocol docs.

## Page context

The page details go straight into the root `attributes` object, not into the report's `events` array. On a browser error report that array only ever holds [glows](#glows) (aka span events).

| Attribute | Type | Description |
|---|---|---|
| `url.full` | string | Full page URL, [redacted](#redaction) |
| `url.query` | string | Query string, without the leading question mark, [redacted](#redaction) |
| `user_agent.original` | string | User agent string |
| `http.request.referrer` | string | Referrer URL, [redacted](#redaction) |
| `document.ready_state` | string | Document ready state when the error was caught |
| `http.request.cookies` | object | Cookies, with sensitive values [redacted](#redaction) |
| `host.name` | string | The page's hostname |

`host.name` is a resource attribute, so it lands in the Hostname column alongside reports from your backend. A PHP client puts the machine hostname there. In a browser the closest equivalent is the hostname of the page.

## Redaction

Flare stores what you send it. It does not scan payloads for secrets and strip them, so a client has to redact before the report leaves the browser. Once a session token is in an error report, it is in Flare.

This matters more in a browser than on a server. Query strings hold password reset tokens and one-time login links, and `document.cookie` gives you the session cookie of whoever hit the error.

### The marker

Replace the value with the string `[redacted]`. Keep the key.

```json
{
    "url.full": "https://acme.test/reset?email=sam@acme.test&token=[redacted]",
    "http.request.cookies": {
        "theme": "dark",
        "session_id": "[redacted]"
    }
}
```

Keeping the key is deliberate. Knowing a `token` parameter was present, and that it was removed on purpose, is more useful than a gap you cannot tell apart from a client that never collected it.

### Match on the name, never the value

Decide what to redact by looking at the parameter name, the cookie name or the object key. Do not inspect values and guess whether something looks like a secret. Value sniffing misses secrets that look ordinary and mangles ordinary data that happens to look like a secret.

For query parameters, decode the key before you test it, so `api%5Fkey` is caught along with `api_key`. If decoding fails on a malformed escape, fall back to the raw key rather than skipping the parameter.

### What to cover

At minimum, redact names matching these: `password`, `passwd`, `pwd`, `token`, `secret`, `authorization`, `auth`, `bearer`, `oauth`, `credential`, `cookie`, `api_key`, `private_key`, `session`, `csrf`, `xsrf`, `pin`, `ssn`, `card_number`, `cvv`. Match case insensitively, and allow both `-` and `_` in the multi-word ones.

Let people extend that list. Applications have their own names for sensitive fields, and the default list cannot know about `acme_impersonation_key`.

Apply it to every place a name-value pair reaches Flare: query strings in `url.full`, `url.query` and `http.request.referrer`, cookie values in `http.request.cookies`, and any route parameters or component props your framework integration collects.

### Strip credentials from URLs

A URL can carry credentials directly, as in `https://sam:hunter2@acme.test/orders`. Remove that part completely rather than replacing it with `[redacted]`, and only look at the authority section, since a path or query can legally contain an `@`.

### Paths are not redacted

Redaction only touches query values, so `/reset/9f2c-token-here` goes to Flare intact. A client cannot fix this: a path segment has no name to match against, and stripping segments would destroy route grouping. Keep that in mind when you decide where a secret goes in a URL.

Traces have the same problem. `url.full` on `browser_pageload`, `browser_navigation`, `browser_fetch` and `browser_xhr` needs the same treatment as it does here.

## Entry point

Every report should say which page the error happened on. The `flare.entry_point.*` attributes carry that at the root of `attributes`. For a browser page, `flare.entry_point.type` is `web` and `flare.entry_point.handler.type` is `browser`. See [Entry points](/docs/protocol/general/entry-points) for the rest.

Code running without a `window`, so server-side rendering or a Node process, has no page to report. Leave the page context attributes out rather than sending empty strings.

## Source maps

`sourcemapVersionId` goes on the report itself, not in `attributes`. See [Sourcemaps](/docs/protocol-javascript/errors/sourcemaps).

Send `columnNumber` on your stack frames. Minified code puts a whole module on one line, so without a column there is no way to work out which of the forty statements on line 1 actually threw.

## React errors

React strips error messages out of production builds and leaves you with a code, like `Minified React error #418`. Send the `flare.exception.react_minified_error` attribute and Flare puts the real message back.

| Field | Type | Description |
|---|---|---|
| `number` | int | The React error code |
| `args` | array | Values that go into the message template, in order |
| `url` | string/null | Link to the decoded error on `react.dev` |
| `react_version` | string | The React version that threw, used to pick the right error code map |

The version matters because React renumbers its error codes between releases. Flare looks up the message for the version you send and uses it as the exception message.

## Glows

Glows are the short notes a developer leaves behind for context. They go in the report's `events` array as span events of type `php_glow`, not in `attributes`. See [Events](/docs/protocol-javascript/general/events#php_glow).

## Browser extension errors

Errors thrown by browser extensions rather than by your own code are dropped by default. Send the `X-Report-Browser-Extension-Errors: true` header if you want them stored. See the [errors payload](/docs/protocol/errors/payload#headers).
