Error Messages

This page documents the error messages produced by DuckDB Semantic Views, their causes, and how to resolve them.

DDL Errors (CREATE SEMANTIC VIEW)

These errors occur at define time when creating or replacing a semantic view.

Missing view name

Missing view name after 'CREATE SEMANTIC VIEW'.

Cause: The CREATE SEMANTIC VIEW statement has no name before AS.

Fix: Add a view name: CREATE SEMANTIC VIEW my_view AS ...

Expected AS or FROM YAML

Expected 'AS' or 'FROM YAML' after view name.

Cause: The statement has a view name but is missing the AS keyword or FROM YAML keywords before the body.

Fix: Use either the keyword body (CREATE SEMANTIC VIEW my_view AS TABLES (...)) or the YAML body (CREATE SEMANTIC VIEW my_view FROM YAML $$ ... $$).

Missing TABLES clause

Missing required clause 'TABLES'.

Cause: The body does not include a TABLES clause.

Fix: Add a TABLES clause as the first clause in the body.

No DIMENSIONS or METRICS

At least one of 'DIMENSIONS' or 'METRICS' is required.

Cause: The body has a TABLES clause but neither DIMENSIONS nor METRICS.

Fix: Add at least one DIMENSIONS or METRICS clause.

Unknown clause keyword

Unknown clause keyword '<word>'; did you mean '<KEYWORD>'?

Cause: A word in the body does not match any known clause keyword (TABLES, RELATIONSHIPS, FACTS, DIMENSIONS, METRICS, MATERIALIZATIONS).

Fix: Check spelling. The error suggests the closest valid keyword.

Duplicate clause

Duplicate clause keyword '<KEYWORD>'.

Cause: The same clause keyword appears more than once.

Fix: Combine entries into a single clause.

Clause out of order

Clause '<KEYWORD>' appears out of order; clauses must appear as: TABLES,
RELATIONSHIPS (optional), FACTS (optional), DIMENSIONS (optional),
METRICS (optional), MATERIALIZATIONS (optional).

Cause: Clauses are not in the required order.

Fix: Reorder clauses to: TABLES, RELATIONSHIPS, FACTS, DIMENSIONS, METRICS, MATERIALIZATIONS.

Unclosed parenthesis

Unclosed '(' for clause '<KEYWORD>'.

Cause: A clause’s opening parenthesis has no matching closing parenthesis.

Fix: Check for mismatched parentheses in the clause body.

Parser strictness

Changed in version 0.11.0: Several malformed statements that earlier releases silently accepted (dropping or mis-storing part of the input) are now rejected. If a statement that used to “work” begins to error after upgrading, it was almost certainly one of these:

  • Stray or leading commas in a clause list are rejected — DIMENSIONS (a AS x,, b AS y) and TABLES (,o AS orders ...) no longer silently drop an entry. A single trailing comma (METRICS (a AS ..., )) is still tolerated.

  • Malformed identifier slots are rejected instead of being stored as unqueryable names: a whitespace-separated multi-token name (o.d junk AS ..., which used to name the dimension d junk) and an empty quoted identifier "" in a name or alias slot now error. An unqualified entry name whose expression happens to contain a dot (region AS upper(o.region)) now reports the missing alias.name qualifier rather than a misleading “Expected ‘AS’”.

  • Trailing tokens after the view name on a name-only statement (DROP / DESCRIBE / SHOW COLUMNS IN SEMANTIC VIEW) are rejected — DROP SEMANTIC VIEW a b c no longer executes and silently discards the extra tokens. ALTER sub-operations do the same.

  • DDL prefix keywords require a word boundaryDROP SEMANTIC VIEWS (plural typo) no longer drops a view named s, and CREATE SEMANTIC VIEWfoo is no longer recognised as CREATE SEMANTIC VIEW.

Duplicate or colliding names

duplicate name '<name>': <kind> '<name>' collides with <kind> '<other>'
-- dimension, metric, and fact names share one namespace and are
case-insensitive

Cause: Two items in the same semantic view share a name. Dimensions, metrics, and facts are resolved from one namespace at query time, so the collision may be within a kind (two metrics named revenue) or across kinds (a dimension and a metric both named amount). The comparison is case-insensitive, so region and Region collide.

Fix: Rename one of the items so that every dimension, metric, and fact name is unique (ignoring case).

-- This will fail: "duplicate name 'Region': dimension 'Region' collides
-- with dimension 'region' ..."
DIMENSIONS (
    o.region AS o.region,
    c.Region AS c.sales_region
)

-- Fix: use distinct names
DIMENSIONS (
    o.order_region AS o.region,
    c.customer_region AS c.sales_region
)
-- This will fail: "duplicate name 'Amount': metric 'Amount' collides
-- with dimension 'amount' ..."
DIMENSIONS (
    o.amount AS o.amount_category
)
METRICS (
    o.Amount AS SUM(o.amount)
)

-- Fix: use a distinct name for the metric
DIMENSIONS (
    o.amount AS o.amount_category
)
METRICS (
    o.total_amount AS SUM(o.amount)
)

Note

The name uniqueness check runs at CREATE (and ALTER) time, before the view definition is persisted. It is independent of the query-time duplicate checks described in the next section, which catch the same dimension or metric being requested twice in a single semantic_view() call. Semantic views created before this check existed keep working at query time: lookups resolve to the first declaration.

Graph validation errors

table '<alias>' cannot reference itself

Relationship graph contains a cycle: <alias1> -> <alias2> -> ...

Diamond detected: table '<alias>' is reachable via multiple paths.
Use named relationships for role-playing dimensions.

Cause: The relationship graph violates tree structure requirements.

Fix:

  • Self-reference: A table cannot have a relationship pointing to itself.

  • Cycle: Follow the chain in the error message to find the circular dependency and remove it.

  • Diamond: If a table is reachable via multiple paths, give each path a unique relationship name (role-playing pattern) or restructure to remove the duplicate path.

Aggregate in FACTS

Fact '<name>' contains aggregate function '<func>'. Facts must be
row-level expressions. Move aggregation to METRICS.

Cause: A fact expression uses an aggregate function like SUM, COUNT, or AVG.

Fix: Move the aggregation to the METRICS clause. Facts are for row-level calculations only.

Circular fact or metric references

Circular dependency detected in facts: <name1>, <name2>, ...

Circular dependency detected in derived metrics: <name1>, <name2>, ...

Cause: Facts or derived metrics reference each other in a cycle.

Fix: Break the cycle by removing or restructuring the circular reference.

NON ADDITIVE BY dimension not found

Added in version 0.6.0.

NON ADDITIVE BY dimension '<dim>' on metric '<name>' does not match any
declared dimension. Did you mean '<suggestion>'?

Cause: A NON ADDITIVE BY clause references a dimension name that does not exist in the view’s DIMENSIONS clause.

Fix: Check the dimension name against the declared dimensions. The error suggests close matches when available.

Window metric inner metric not found

Added in version 0.6.0.

Window metric '<name>': inner metric '<inner>' not found in semantic view
metrics. Did you mean '<suggestion>'?

Cause: A window function metric wraps another metric (e.g., AVG(total_qty) OVER (...)), but the inner metric total_qty does not exist in the METRICS clause.

Fix: Ensure the inner metric is declared before the window metric. The error suggests close matches.

Window metric EXCLUDING dimension not found

Added in version 0.6.0.

Window metric '<name>': EXCLUDING dimension '<dim>' not found in semantic
view dimensions. Did you mean '<suggestion>'?

Cause: A window metric’s PARTITION BY EXCLUDING clause references a dimension that does not exist.

Fix: Check the dimension name. The error suggests close matches. All dimensions in EXCLUDING must be declared in the view’s DIMENSIONS clause.

Window metric PARTITION BY dimension not found

Added in version 0.6.0.

Window metric '<name>': PARTITION BY dimension '<dim>' not found in semantic
view dimensions. Did you mean '<suggestion>'?

Cause: A window metric’s PARTITION BY clause (without EXCLUDING) references a dimension that does not exist in the view’s DIMENSIONS clause.

Fix: Check the dimension name. The error suggests close matches. All dimensions in PARTITION BY must be declared in the view’s DIMENSIONS clause.

Window metric ORDER BY dimension not found

Added in version 0.6.0.

Window metric '<name>': ORDER BY dimension '<dim>' not found in semantic
view dimensions. Did you mean '<suggestion>'?

Cause: A window metric’s ORDER BY clause references a dimension that does not exist in the view’s DIMENSIONS clause.

Fix: Check the dimension name. The error suggests close matches.

OVER and NON ADDITIVE BY conflict

Added in version 0.6.0.

Cannot combine OVER clause with NON ADDITIVE BY on metric '<name>'.
Use one or the other.

Cause: A metric definition includes both a window function OVER (...) clause and a NON ADDITIVE BY (...) clause. These are mutually exclusive features.

Fix: Use either NON ADDITIVE BY (for semi-additive snapshot aggregation) or OVER (for window functions), not both on the same metric.

OVER clause not allowed on derived metric

Added in version 0.6.0.

OVER clause not allowed on derived metric '<name>'. Only qualified metrics
(alias.name) can use OVER.

Cause: A derived metric (one without a table alias) has an OVER clause. Window metrics require a qualified name (alias.metric_name) because they need a source table for join resolution.

Fix: Add a table alias to the metric name: change my_metric AS AVG(total) OVER (...) to alias.my_metric AS AVG(total) OVER (...).

Materialization Errors

Added in version 0.7.0.

These errors occur when validating the MATERIALIZATIONS clause.

Duplicate materialization name

Duplicate materialization name '<name>'.

Cause: Two or more materializations in the same view share the same name.

Fix: Give each materialization a unique name.

Materialization dimension not found

Materialization '<name>': dimension '<dim>' not found in semantic view
dimensions. Did you mean '<suggestion>'?

Cause: A materialization references a dimension name that does not exist in the view’s DIMENSIONS clause.

Fix: Check the dimension name against the declared dimensions. The error suggests close matches.

Materialization metric not found

Materialization '<name>': metric '<met>' not found in semantic view
metrics. Did you mean '<suggestion>'?

Cause: A materialization references a metric name that does not exist in the view’s METRICS clause.

Fix: Check the metric name against the declared metrics. The error suggests close matches.

Empty materialization coverage

Materialization '<name>': must specify at least one of DIMENSIONS or METRICS.

Cause: A materialization entry declares only a TABLE with neither DIMENSIONS nor METRICS.

Fix: Add at least one of DIMENSIONS (...) or METRICS (...) to the materialization entry.

YAML Errors

Added in version 0.7.0.

These errors occur when using FROM YAML or FROM YAML FILE to create a semantic view, or when exporting with READ_YAML_FROM_SEMANTIC_VIEW().

Dollar-quote errors

Expected '$' to begin dollar-quoted string

Unterminated dollar-quote opening delimiter

Unterminated dollar-quoted string (expected closing '<delimiter>')

Cause: The FROM YAML body is not properly enclosed in dollar-quote delimiters.

Fix: Ensure the YAML content starts with $$ (or $tag$) and ends with the matching closing delimiter.

Trailing content after dollar-quote

Unexpected content after closing dollar-quote: '<text>'

Cause: Extra text appears after the closing $$ delimiter.

Fix: Remove any content between the closing $$ and the statement terminator.

Empty file path

File path cannot be empty.

Cause: FROM YAML FILE was used with an empty single-quoted string.

Fix: Provide a valid file path: FROM YAML FILE '/path/to/file.yaml'

Missing file path quotes

Expected single-quoted file path after FILE keyword.

Cause: The file path after FROM YAML FILE is not enclosed in single quotes.

Fix: Use single quotes around the file path: FROM YAML FILE '/path/to/file.yaml'

YAML size limit exceeded

YAML definition for semantic view '<name>' exceeds size limit
(<size> bytes > <cap> bytes).

Cause: The YAML content exceeds the 1 MiB (1,048,576 bytes) size cap.

Fix: Reduce the YAML definition size, or split the semantic view into multiple smaller views.

YAML parsing error

YAML deserialization error: <details>

Cause: The YAML content is not valid YAML or does not match the expected semantic view definition schema.

Fix: Check the YAML syntax and structure. The definition must include tables, and at least one of dimensions or metrics.

Query Errors (semantic_view)

These errors occur at query time when calling semantic_view() or explain_semantic_view().

View not found

Semantic view '<name>' not found. Did you mean '<suggestion>'?
Available views: [<list>].
Run FROM list_semantic_views() to see all registered views.

Cause: No semantic view with the given name exists.

Fix: Check the view name. The error shows available views and suggests close matches.

Empty request

semantic view '<name>': specify at least dimensions := [...], metrics := [...],
or facts := [...].
Run DESCRIBE SEMANTIC VIEW <name> to see available dimensions, metrics, and facts.

Cause: Neither dimensions, metrics, nor facts was specified in the query.

Fix: Add at least one of dimensions := [...], metrics := [...], or facts := [...].

Unknown dimension

semantic view '<view>': unknown dimension '<name>'. Available: [<list>].
Did you mean '<suggestion>'?

Cause: A requested dimension name does not match any dimension in the view.

Fix: Check the dimension name. Use DESCRIBE SEMANTIC VIEW to see all available dimensions.

Unknown metric

semantic view '<view>': unknown metric '<name>'. Available: [<list>].
Did you mean '<suggestion>'?

Cause: A requested metric name does not match any metric in the view.

Fix: Check the metric name. Use DESCRIBE SEMANTIC VIEW to see all available metrics.

Duplicate dimension or metric

semantic view '<view>': duplicate dimension '<name>'

semantic view '<view>': duplicate metric '<name>'

Cause: The same dimension or metric appears more than once in the request. Duplicates are detected on the resolved item, so requesting both the bare and the table-qualified spelling of the same item ('region' and 'o.region') is also rejected.

Fix: Remove the duplicate from the dimensions or metrics list.

COUNT(*) on a joined table requires a PRIMARY KEY

semantic view '<view>': metric '<name>' uses COUNT(*) on joined table
'<alias>'. The generated LEFT JOIN produces one NULL-extended row per
base-table row with no match in '<alias>', which COUNT(*) would count --
so the expansion rewrites COUNT(*) to COUNT(<primary key>) for non-base
tables, but table '<alias>' has no PRIMARY KEY declared in the TABLES
clause. Add PRIMARY KEY (cols) to '<alias>' or use an explicit column:
COUNT(<alias>.<column>).

Cause: A queried metric (directly, via a derived metric, or as a window metric’s inner aggregate) is COUNT(*) on a table other than the base table. Generated joins are LEFT JOINs, so COUNT(*) would also count the NULL-extended row produced for each base row with no match — silently inflating the result. The expansion protects against this by rewriting COUNT(*) to COUNT(<first primary key column>) for non-base source tables, which requires the table to declare a PRIMARY KEY.

Fix: Declare PRIMARY KEY (<cols>) for the metric’s source table in the TABLES clause, or define the metric as COUNT(<alias>.<column>) over a NOT NULL column.

Fan trap detected

semantic view '<view>': fan trap detected -- metric '<metric>' (table '<table>')
would be duplicated when joined to dimension '<dim>' (table '<table>') via
relationship '<rel>' (many-to-one cardinality, inferred: FK is not PK/UNIQUE).
This would inflate aggregation results. Remove the dimension, use a metric from
the same table, or restructure the relationship.

Cause: The query would traverse a one-to-many join boundary, inflating aggregate results.

Fix: See How to Understand and Avoid Fan Traps for detailed solutions: remove the problematic dimension, use a metric from the same table as the dimension, or restructure the view.

Ambiguous dimension path

semantic view '<view>': dimension '<dim>' is ambiguous -- table '<table>'
is reached via multiple relationships: [<rel1>, <rel2>]. Specify a metric
with USING to disambiguate, or use a dimension from a non-ambiguous table.

Cause: A dimension comes from a table reachable via multiple named relationships (role-playing pattern), and no co-queried metric has a USING clause that selects one path.

Fix: See How to Model Role-Playing Dimensions. Add a metric with USING (<rel_name>) to disambiguate, or use a dimension from a table that is not a role-playing target.

Metric cannot be co-queried with a semi-additive metric

semantic view '<view>': metric '<name>' (expression: <expr>) cannot be
co-queried with semi-additive metric '<semi>': <reason>. Snapshot expansion
for NON ADDITIVE BY requires every co-queried metric to be a single
aggregate call SUM/COUNT/AVG/MIN/MAX(<expression>) without '*', DISTINCT,
or surrounding expression text. Query '<name>' and '<semi>' separately.

Cause: The query mixes an active semi-additive metric (its NON ADDITIVE BY dimension is not in the query) with a metric whose expression cannot be decomposed for the snapshot CTE: COUNT(*), a DISTINCT aggregate, arithmetic around the aggregate (SUM(x) * 0.1), a wrapped aggregate (COALESCE(SUM(x), 0)), or a derived metric.

Fix: Query the two metrics separately, or redefine the co-queried metric as a single bare aggregate call (e.g. COUNT(<pk_column>) instead of COUNT(*)).

Semi-additive metric expression cannot be expanded

semantic view '<view>': semi-additive metric '<name>' (expression: <expr>)
cannot be expanded: <reason>. NON ADDITIVE BY snapshot expansion requires
the metric to be a single aggregate call SUM/COUNT/AVG/MIN/MAX(<expression>)
without '*' or DISTINCT.

Cause: The NON ADDITIVE BY metric’s own expression is not a single decomposable aggregate call, so the snapshot CTE cannot split it into a per-row column plus an outer re-aggregation.

Fix: Redefine the metric as a single aggregate call over a plain expression (e.g. SUM(a.balance)).

Private metric

Added in version 0.6.0.

semantic view '<view>': metric '<name>' is private and cannot be queried
directly. Private metrics can only be used in derived metric expressions.

Cause: A metric marked PRIVATE was requested in the metrics := [...] list.

Fix: Private metrics exist for internal composition only. Query a public derived metric that uses the private metric, or recreate the view without the PRIVATE keyword. See How to Use Metadata Annotations.

Private fact

Added in version 0.6.0.

semantic view '<view>': fact '<name>' is private and cannot be queried
directly. Private facts can only be used in derived expressions.

Cause: A fact marked PRIVATE was requested in the facts := [...] list.

Fix: Remove the PRIVATE keyword from the fact to make it queryable, or reference the fact only from metric expressions.

Cannot combine facts and metrics

Added in version 0.6.0.

semantic view '<view>': cannot combine facts and metrics in the same query.
Use facts := [...] OR metrics := [...], not both.

Cause: The query includes both facts := [...] and metrics := [...]. Facts are row-level expressions; metrics are aggregated. These modes are mutually exclusive.

Fix: Run two separate queries – one for facts and one for metrics.

Unknown fact

Added in version 0.6.0.

semantic view '<view>': unknown fact '<name>'. Available: [<list>].
Did you mean '<suggestion>'?

Cause: A requested fact name does not match any fact in the view’s FACTS clause.

Fix: Check the fact name against declared facts. The error suggests close matches.

Duplicate fact

Added in version 0.6.0.

semantic view '<view>': duplicate fact '<name>'

Cause: The same fact name appears more than once in the facts := [...] list.

Fix: Remove the duplicate from the facts list.

Incompatible table paths for facts

Added in version 0.6.0.

Changed in version 0.12.0: The rule is now about row multiplication rather than tree position, and the message wording changed to match. Pairs that are reachable one way without fanning out — a fact on a table that references the base table, with a dimension on a table the base table references — are now accepted.

semantic view '<view>': fact query references objects from incompatible
table paths -- neither table '<table_a>' nor '<table_b>' can be reached
from the other without crossing a one-to-many relationship, so joining
them would duplicate the rows returned

Cause: A fact query does not aggregate, so it returns rows as they are. Reaching one of these two tables from the other means traversing a one-to-many relationship against its direction — every row on one side matching many on the other — and that holds whichever of the two you start from. The rows returned would silently be duplicates. The usual shape is two tables that both reference a third (line_items and shipments both referencing orders): joining both multiplies each one’s rows by the other’s.

Fix: Query the two tables separately. Facts and dimensions can be combined freely as long as one side is reachable from the other without fanning out — a chain of many-to-one relationships in either direction is fine, however long.

Window and aggregate metric mixing

Added in version 0.6.0.

semantic view '<view>': cannot mix window function metrics [<window_metrics>]
with aggregate metrics [<aggregate_metrics>] in the same query

Cause: The query requests both window function metrics and standard aggregate metrics. These produce different result shapes (row-level vs. grouped) and cannot be combined.

Fix: Run separate queries for window metrics and aggregate metrics.

Window metric required dimension missing

Added in version 0.6.0.

semantic view '<view>': window function metric '<metric>' requires
dimension '<dim>' to be included in the query (used in <reason>)

Cause: A window function metric references a dimension in its PARTITION BY EXCLUDING, PARTITION BY, or ORDER BY clause, but that dimension was not included in the query’s dimensions := [...] list. The <reason> value indicates which clause requires the dimension (PARTITION BY EXCLUDING, PARTITION BY, or ORDER BY).

Fix: Add the required dimension to the query. Use SHOW SEMANTIC DIMENSIONS FOR METRIC to see which dimensions are required (required = TRUE) for a window metric.

Concurrent DDL Errors

These errors relate to DROP or ALTER SEMANTIC VIEW when another writer modifies the catalog around the same time.

Existence guard on DROP / ALTER (and its autocommit window)

A non-IF EXISTS DROP or ALTER runs a small existence check before its DELETE / UPDATE. When the view is absent at check time you get:

semantic view '<name>' does not exist

and ALTER ... RENAME additionally raises, when the target name is taken:

semantic view '<new_name>' already exists

Cause: The view was not present (or the rename target was already present) when the guard evaluated – either it never existed, or another connection had already committed the change by the time your statement ran.

A subtlety under autocommit: the guard and the DELETE / UPDATE are separate statements. Under autocommit (the default) they commit independently, so a concurrent commit that lands in the window between them is not caught by the guard: a concurrent DROP leaves your DROP deleting 0 rows and reporting success, and a rename target taken in that window surfaces a raw Constraint Error: Duplicate key from DuckDB instead of the friendly already exists message.

Fix: Decide on the contract you want. Use IF EXISTS if a missing target should silently no-op (DROP SEMANTIC VIEW IF EXISTS my_view, ALTER SEMANTIC VIEW IF EXISTS my_view ...). If you need the check and the write to be atomic under concurrency, wrap the statement in an explicit transaction (BEGIN; DROP SEMANTIC VIEW my_view; COMMIT;): all statements then share one snapshot, and a conflicting concurrent commit makes your COMMIT fail with a retryable transaction-conflict error instead of slipping through the window. See Transactional DDL and Known Limitations for the full mechanism.

Wildcard Errors

Added in version 0.6.0.

These errors occur when using alias.* wildcard patterns in dimensions, metrics, or facts parameters.

Unqualified wildcard

unqualified wildcard '*' is not supported. Use table_alias.* to select
all items for a specific table.

Cause: A bare * was used without a table alias prefix.

Fix: Use alias.* instead of *. For example: dimensions := ['o.*'] to select all dimensions from the o table alias.

Unknown table alias in wildcard

unknown table alias '<alias>' in wildcard '<alias>.*'. Available aliases:
[<list>]

Cause: The table alias in a wildcard expression does not match any alias declared in the view’s TABLES clause.

Fix: Check the alias name against the declared table aliases. The error lists all available aliases.

Near-Miss DDL Detection

The extension detects near-miss DDL statements and provides helpful suggestions:

Did you mean 'CREATE SEMANTIC VIEW'?

Did you mean 'DROP SEMANTIC VIEW'?

This triggers when the input is close to a valid semantic view DDL prefix but contains a typo (e.g., CREAT SEMANTIC VIEW or DROP SEMANTC VIEW). The detection uses Levenshtein distance with a threshold of 3 edits.