Skip to content

Errors

The publish finding envelope and its layers, every semantic check code, the refresh failure classes, and the named refusals you will meet.

Dashies refuses in three different places, and which one you hit tells you what to do about it.

WhereWhenWhat survives
PublishBefore anything is writtenNothing was published. Fix and republish.
RefreshOn a schedule, unattendedThe last good body stays live. The run is recorded as failed.
The published pageWhile a reader is looking at itThe tile states a reason in place. See Honest degradation.

The publish finding envelope

A failed publish reports every finding at once, in a fixed shape:

Publish failed - 2 errors (nothing was published):
- [semantic] /datasets/revenue/measures/arr: measure `arr` divides one aggregate by another ...
- [compile] /tiles/3/measure: a pie cannot display a "cents"/"points"-scaled measure ...

Warnings use a separate line and do not stop the publish:

warning: [compile] /datasets/revenue/sql: ...

The bracketed word is the layer, and the path is a JSON pointer into your spec.

LayerWhat it means
argA tool argument is wrong: the path, the metadata, a spec_edits entry.
identityThe document does not name the dashboard you are publishing to: a slug mismatch, or a look.from that does not resolve.
steerThe dataset mode could not be resolved and you have to declare it.
semanticThe spec is well-formed but the seeded data contradicts what it declares.
compileThe spec cannot be turned into a page, or the page is over the publish cap.
seedA dataset's SQL did not run, or did not return the whole result.
conflictThe stored spec moved under you. Re-read and re-apply.
writeThe bytes or the row could not be stored.
internalA bug on our side. Nothing was published; please report it.

At most ten semantic findings are reported per publish, errors first. When more exist, a findings_truncated entry says how many of which severity were cut. Fix what is listed and re-run to see the rest.

Semantic checks

These run against the seeded data, not just the spec, which is why they can catch a declaration the data contradicts. An error blocks the publish; a warning does not.

CodeSeverityWhat it caught
col_missingerrorA declared dimension or measure has no matching output column.
col_extraerrorAn undeclared output column would ship as public island bytes. Declare it or drop it from the query.
type_not_numericerrorA measure needs a numeric column and its output column is not one.
agg_mismatcherrorThe measure declares one aggregate and the query computes another.
count_not_integererrorA count measure seeded non-integer values, so it is really an average.
predivided_ratioerrorA measure divides one aggregate by another in SQL. That re-sums wrong under viewer filters. Declare a ratio measure instead.
hybrid_rows_missing_columnerrorA hybrid measure's source column is absent from rows_sql, so the row-level path cannot recompute it.
lattice_no_grand_totalerrorThe lattice has no all-rolled-up cell, so the unfiltered dashboard boots blank.
seed_emptyerrorThe dataset seeded zero rows, so nothing it declares can be verified.
seed_truncatederrorThe island holds fewer rows than the dataset really has. The missing cells would refresh silently wrong.
seed_probe_unavailableerrorThe completeness probe returned no count, so there is no evidence the island is whole.
rate_shaped_sumwarningA sum over values all between 0 and 1. Summing rates is usually wrong.
percent_points_suspectwarningA measure declared percent/fraction seeded values that look like 0 to 100.
date_dim_not_isowarningA date dimension seeded non-ISO values. Bucket to YYYY, YYYY-MM or YYYY-MM-DD in SQL.
domain_drift_at_publishwarningA seeded value falls outside its declared domains, so the runtime filter will drop it.
series_cardinalitywarningMore distinct series values than the five-colour mark palette.
slice_cardinalitywarningMore distinct slices than a pie or donut will draw.
funnel_stage_absentwarningA declared funnel stage matches no seeded value, so it renders as absent.
stack_percent_mixed_signwarningA stack: percent column seeds both positive and negative segments, so its shares would be no true proportion.
manual_cross_checkadvisoryA dataset is built over more than one row source.

`manual_cross_check` is the one no static check can close

A join that matches more than one row per key silently multiplies every additive measure, and nothing in the pipeline can see it. Two things make it worse than it sounds:

On a lattice or hybrid, each cell is still the exact aggregate of the duplicated rows, so every subtotal reconciles with every total and the dashboard looks internally consistent. Checking it against itself finds nothing. Measured at roughly 150 times inflation on a real star schema.

A rows dataset does not escape it by deferring the aggregation: the duplicated rows are already baked into the published island, and the query engine then aggregates them correctly and returns the inflated number.

The only thing that finds it is a comparison against an independent direct aggregate: Verify your numbers.

Named publish refusals

CodeWhat happened
over_publish_capThe compiled body is over the publish limit. The message names the byte count and the heaviest dataset.
spec_conflictThe stored spec changed since you read it. Re-read with get_dashboard_spec and re-apply.
spec_base_staleYour base_spec_hash no longer names the stored spec: it was republished after you read it.
spec_ref_unknownA spec_hash names neither the stored spec nor a document still held server-side. Send the document.
spec_too_largeThe result of applying spec_edits is over the spec byte limit.
slug_mismatchThe spec's slug differs from the publish path. The path is the target; rename with update_dashboard.
look_from_no_bodylook: { from } points at a dashboard with no published body to inherit.
look_from_mismatchlook: { from } must equal the publish target slug. To reuse another dashboard's body, read it and inline it.
custom_html_scriptA <script> in a custom tile's html is inert. Move runtime code to the tile's js.
null_leading_dimensionA dimension's leading value is null.
timezone_bucketThe SQL buckets a date without naming a zone, or with an ambiguous single AT TIME ZONE.
parquet_pendingNot a failure: a Parquet-backed dataset publishes with no data, and its tiles read "Updating" until the first refresh extracts the rows.
compiler_invariant, internal_errorA bug on our side. Nothing was published; please report it.

Refresh failure classes

A scheduled refresh that fails records one class on the run. The last good body stays live, so a reader never sees a half-refreshed dashboard.

ClassRecorded messageWhat to do
connection_authwarehouse connection authentication failedThe credential is wrong or revoked. Rotate it in the web app.
connection_unreachablewarehouse was unreachableNetwork, firewall, or a paused warehouse.
connection_timeoutwarehouse query timed outThe cube is too slow for the refresh budget. Narrow it.
ssl_failedwarehouse TLS/SSL negotiation failedA TLS problem at the warehouse.
schema_driftwarehouse schema changed; cube query no longer matchesA table or column was renamed or dropped. Resync and fix the SQL.
cube_errorwarehouse cube query failedEverything else the query raised.
tier_lapsedthe plan that pays for this dashboard's refresh has lapsed; paused until it is upgradedNot a failure of the query. It resumes on upgrade.
connection_removeddata connection is no longer activeThe connection was deleted or disabled. Dependent dashboards were paused.

Only three of those are evidence the connection itself is unhealthy: connection_auth, ssl_failed and connection_unreachable. The rest are about one dashboard's query, which is why a connection can read active while one of its dashboards keeps failing.

`connection_timeout` is deliberately not a connection-health signal

A timeout means a slow cube on a healthy warehouse. Counting it would flip a connection to failing because one dashboard grew too big, and take every other dashboard on that connection with it.

Never the raw driver text: the executor drops the message and the detail before the class is recorded, because they carry the remote host, user, database and port.

Authentication failures

A request to the web app carrying an unusable session cookie returns 401 {"ok":false,"error":"unauthenticated (<reason>)"}. The reason is a stable machine token, mainly for log analysis:

ReasonMeaning
no_cookieNo session cookie was sent.
malformedThe cookie or its token could not be parsed.
expiredThe token is past its expiry.
invalid_signatureThe signature did not verify.
wrong_issuerThe token was issued by something else.
wrong_audienceThe audience claim does not match: for example an anon key used as a session.
no_subThe token carries no subject.
fetch_failedThe signing keys could not be fetched. Transient.

Any of these means sign in again. An MCP tool never surfaces these: the client re-runs the browser flow on its own. See the authorization flow.

Check it worked

Publish with dry_run: true first. It runs the whole pipeline, seed included, and writes nothing, so every finding above is reachable without creating a dashboard. A clean dry run and a failing real publish differ only in the write layer.