Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / UI

A failing query

automatic in-page failure · .osy-query-failed · .osy-query-failed-message · .osy-query-failed-retry

When a query a region reads fails or is refused, that region shows the failure in place — the server's own sentence, the correlation id to look it up by, and a Retry — instead of rendering as empty. It is automatic: you write nothing. The rest of the page keeps working, because only the data is missing.

stable1 example compiled by CIuiqueryerrorfailure

Summary#

When a region reads a query that fails — the server refused it, the request errored, the connection dropped — that region renders the failure where the rows would have been. You write nothing; any foreach over a query member gets it.

It exists because the alternative is silence. A failed query has no rows, and a region with no rows renders as empty — so a table the user is not allowed to see looked exactly like a table with nothing in it. That is not a small confusion: it is the difference between "there are no expenses" and "you were refused", and the user cannot tell which they are looking at.

The failure is in-page, not a whole-page error screen. The page rendered fine and its other controls still work, so replacing all of it would misdescribe what broke: only the data is missing. A page whose other half is a form the user was half-way through filling in must not lose that form because a list beside it failed to load.

For a page that fails to load at all — no data, no render — the app's error surface is the right thing; that is a different situation with a different answer. For the waiting state before an answer arrives, see Pending.

Signature#

// Automatic — no code. A `foreach` over a query whose fetch failed renders the failure in place of its rows.

The rendered affordance, for styling:

ClassWhat it is
.osy-query-failedthe container (carries role="alert")
.osy-query-failed-messagethe server's sentence, or the transport error when there is none
.osy-query-failed-correlationthe correlation id — present only when the failure carried one
.osy-query-failed-retrythe Retry button

Examples#

Nothing here opts in — the foreach is ordinary, and the affordance appears only if the read is refused or errors:

[Principal] entity User { [Required] string Email; }

entity ExpenseLine {
  [Required] string Description;
  decimal Amount;
  security { allow read where CreatedBy == user.Id; }   // a refusal here is what the affordance reports
}

[Page("/expenses")] [Render(CSR)]
component Expenses() {
  live var lines = ExpenseLine.OrderBy(l => l.Description).ToList();
  render {
    Stack(gap: 2) {
      // No failure handling written here: if this query is refused, the failure renders in place of the rows.
      foreach (var l in lines) { Text(l.Description); }
    }
  }
}

Description#

What it says. The message prefers the server's own sentence over the transport's. A refusal that says "You do not have access to these lines." is worth showing; GET /query/… failed: 403 tells the user nothing they can act on. When the failure carries no sentence of its own — a dropped connection, a DNS failure — the transport's message is shown instead, because something specific always beats a blank box.

The correlation id is the id to run osy logs --correlation <id> with. It appears when the failure carried one, so whoever hit the problem can report which failure they hit. A failure a user cannot report is most of the way to a failure nobody can fix.

Retry re-runs that query and nothing else. On success the affordance disappears and the rows render through the ordinary path; on a second failure it stays, with whatever the server said this time. Retrying does not reload the page or re-run the page's other queries.

It is entirely client-side, and it is mechanism. The platform draws a plain container with osy- classes — the same arrangement as the built-in .osy-spinner — and an app restyles it in its own CSS alongside every other control state.

Scope. It covers a region reading a query member: a foreach over one, including an inline query. A query that succeeds renders no affordance at all.

Examples#

The common case is nothing — this is automatic:

component ReportDetail(ExpenseReport report) {
  query lines = ExpenseLine.Where(l => l.Report == report);
  render {
    Text(report.Title);              // still renders if `lines` fails
    foreach (var l in lines) {       // if the query is refused, THIS region shows why, with a Retry
      Text(l.Merchant);
    }
    Button("Save", onPress: Save);   // still works
  }
}

Restyling it to match your app:

.osy-query-failed {
  display: flex; align-items: center; gap: .75rem;
  padding: .75rem 1rem; border: 1px solid var(--danger-border); border-radius: 6px;
}
.osy-query-failed-correlation { font: 12px/1 monospace; opacity: .6; }

See also#

Related

Pending

When a control's action waits on the server, the platform shows a busy spinner and disables the control — but only…

Connection

The live state of the browser's link to the server, and the two verbs that recover it. A component you nominate as your…

component

The one archetype for all UI: a bounded reactive unit — typed props, reactive members (fields, `live`…

public pages (what a signed-out visitor can see and do)

A public page, its public data and its public actions are three separate declarations. `[AllowAnonymous]` on a…