Error Messages¶
This page documents the error messages produced by DuckDB Semantic Views, their causes, and how to resolve them.
Load Errors¶
These errors occur when LOAD semantic_views runs.
Built for a different DuckDB release¶
Changed in version 0.15.0: This release is built for DuckDB 2.0. Earlier releases were built for DuckDB 1.5, and v0.14.2 is the latest release for 1.5.
semantic_views was built for DuckDB <built> and cannot run in DuckDB <host>,
because it depends on that exact DuckDB release. If a semantic_views build
for this DuckDB has been published, install it with: FORCE INSTALL
semantic_views FROM community;
DuckDB prefixes the message with An error was thrown during initialization of the extension '<path>':.
Cause: Each build of the extension is compiled against one exact DuckDB release. The file being loaded was built for <built>, but the running DuckDB is <host>. The extension checks this before it starts, so the LOAD fails instead of crashing DuckDB. A common source is an extension file installed before a DuckDB upgrade or downgrade.
Fix: Run SELECT version(); to see which DuckDB you are running, then install the build that matches it and load it. FORCE INSTALL replaces the installed file even when one is already present:
FORCE INSTALL semantic_views FROM community;
LOAD semantic_views;
If no build for <host> has been published yet, the install fails. Until one is, run DuckDB <built>. The latest release for DuckDB 1.5 is v0.14.2.
When <host> is a development or nightly DuckDB build (its version contains a -, such as v2.0.1-dev42), the message ends with Load a semantic_views build compiled against this DuckDB. instead. The community repository only has builds for tagged releases, so build the extension from source against that DuckDB.
DDL Errors (CREATE SEMANTIC VIEW)¶
These errors occur at define time when creating or replacing a semantic view.
Expected AS, TABLES or FROM YAML¶
Expected 'AS', 'TABLES' or 'FROM YAML' after view name. Use: CREATE SEMANTIC
VIEW name [AS] TABLES (...) DIMENSIONS (...) METRICS (...) or: ...
Cause: The statement has no view name (CREATE SEMANTIC VIEW AS ... reads AS as the name), or the text after the view name is neither a body starting with AS or TABLES nor FROM YAML.
Fix: Use either the keyword body (CREATE SEMANTIC VIEW my_view TABLES (...), with or without AS before 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.
No tables in TABLES¶
A semantic view needs at least one table in TABLES.
Cause: The TABLES clause is empty: TABLES ().
Fix: List the view’s tables in TABLES, for example TABLES (o AS orders PRIMARY KEY (id)).
No dimension or metric¶
A semantic view needs at least one dimension or metric.
Cause: The DIMENSIONS and METRICS clauses that the body has are all empty, as in DIMENSIONS () METRICS () or a lone METRICS (). Facts alone do not count: a view is queried through its dimensions and metrics.
Fix: Declare at least one dimension or metric.
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, VARIABLES, 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), VARIABLES (optional), FACTS (optional),
DIMENSIONS (optional), METRICS (optional), MATERIALIZATIONS (optional).
Cause: Clauses are not in the required order.
Fix: Reorder clauses to: TABLES, RELATIONSHIPS, VARIABLES, FACTS, DIMENSIONS, METRICS, MATERIALIZATIONS.
Unclosed parenthesis¶
Unclosed '(' in 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)andTABLES (,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 dimensiond 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 missingalias.namequalifier 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 cno longer executes and silently discards the extra tokens.ALTERsub-operations do the same.DDL prefix keywords require a word boundary –
DROP SEMANTIC VIEWS(plural typo) no longer drops a view nameds, andCREATE SEMANTIC VIEWfoois no longer recognized asCREATE SEMANTIC VIEW.
Malformed quoted identifier¶
Changed in version 0.15.0: DuckDB 2.0 rejects these statements before the extension sees them, so the
messages are DuckDB’s own. Earlier releases reported
Unterminated quoted identifier and empty quoted identifier.
Parser Error: unterminated quoted identifier
Parser Error: zero-length delimited identifier
Cause: A double-quoted identifier in a semantic-view statement has no closing " (for example ORDER BY "unclosed ASC in a window metric, or SHOW SEMANTIC VIEWS IN SCHEMA "oops), or is empty (TABLES ("" AS orders ...)).
Fix: Close the quote, or give the identifier a name. Quote only names that need it (spaces, special characters, reserved words): DuckDB matches identifiers case-insensitively whether they are quoted or not, so quoting does not change which name matches.
Syntax errors in semantic-view statements¶
Changed in version 0.16.0: A statement the grammar cannot match gets DuckDB’s own syntax error. Earlier
releases answered some of them with the extension’s messages, such as
Did you mean 'CREATE SEMANTIC VIEW'?, Missing view name after DDL
prefix. or semantic-view DDL must be sent as its own statement.
Parser Error: syntax error at or near "CREAT"
LINE 1: CREAT SEMANTIC VIEW sales AS ...
^^^^^
Cause: The semantic-view statements are part of DuckDB’s grammar, so a statement that does not match any of them is a syntax error at the first token that does not fit, as for DuckDB’s own SQL. Common causes:
A misspelt keyword:
CREAT SEMANTIC VIEW,DROP SEMANTC VIEW.A missing view name, or an
ALTER SEMANTIC VIEWwith no operation.A view name that is a DuckDB reserved word written without quotes, such as
CREATE SEMANTIC VIEW select AS ...orDESCRIBE SEMANTIC VIEW order. DuckDB accepts its reserved keywords, and most of itstype_functionkeywords such asleftandjoin, as a name only when it is quoted;duckdb_keywords()lists both kinds.A connection that was already open when another connection ran
LOAD semantic_views. It parses without the semantic-view statements until it runs a statement DuckDB parses on its own, so retrying the failed statement fails again (see How the Extension Joins DuckDB’s Parser).
Fix: Correct the token the pointer marks. Quote a reserved-word name (CREATE SEMANTIC VIEW "select" AS ...); GET_DDL quotes such names for you. On a connection opened before the LOAD, run LOAD semantic_views (or any other statement, such as SELECT 1) on it first, then the semantic-view statement.
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.
Members that do not bind¶
Changed in version 0.17.0: CREATE now binds every member. Before, a member DuckDB could not bind was
stored, and its error appeared only when a query reached it.
semantic view '<view>': <kind> '<name>' does not bind: <DuckDB error>
Cause: CREATE binds each dimension, fact and metric in a query of its own against the view’s tables, as Snowflake compiles each expression at CREATE. DuckDB cannot bind the member the message names: its expression refers to a column, table or function that does not exist, has a syntax error, or passes an argument DuckDB rejects. The rest of the message is DuckDB’s own error. PRIVATE members are bound too, and every CREATE form is checked: OR REPLACE, IF NOT EXISTS, FROM YAML and FROM YAML FILE. When every member binds, each table in TABLES is resolved as well; <kind> is then table and <name> the table’s alias, for a table that does not exist even if no member reads it, or a table defined by a query whose query DuckDB cannot bind.
Fix: Correct the expression, or create the missing table, column or function before the view.
-- This will fail: "semantic view 'orders_v': dimension 'fn' does not bind:
-- Conversion Error: extract specifier "fortnight" not recognized"
DIMENSIONS (
o.fn AS date_trunc('fortnight', o.ordered_at)
)
-- Fix: use a date part DuckDB knows
DIMENSIONS (
o.week AS date_trunc('week', o.ordered_at)
)
Tables defined by a query¶
Added in version 0.18.0.
An inline query in TABLES needs an alias: write 'alias AS (<query>)'.
Invalid inline query for table '<alias>': <reason>.
table '<alias>' has an invalid inline query: <reason>
table '<alias>' has both a table name and a definition; give one
Cause: A table defined by a query needs an alias, and its query must stay one query inside the parentheses every expansion reads it through. <reason> says what is wrong: the query is empty, a comment, string or quoted name in it is never closed, its brackets do not nest, it holds a ;, or it holds a prepared-statement parameter ($1, ?), which has no value inside the view’s definition. The last two forms come from FROM YAML, where the table has definition:. There the query also cannot hold a comment, which CREATE from the view’s GET_DDL would drop, and a table cannot have both table: and definition:.
Fix: Give the query an alias, and write it as one complete query. Remove a comment from a YAML definition. Move a parameter into the WHERE clause of a SEMANTIC_VIEW(...) query.
-- This will fail: "An inline query in TABLES needs an alias"
TABLES ((SELECT * FROM orders WHERE amount > 0) PRIMARY KEY (id))
-- Fix
TABLES (paid AS (SELECT * FROM orders WHERE amount > 0) PRIMARY KEY (id))
Variables¶
Added in version 0.18.0.
VARIABLES needs at least one variable: 'name [type] [DEFAULT <expr>]'.
variable '<name>' is declared twice
variable '<name>' has the name of a <kind>; a variable can't share a name with a fact, dimension or metric
variable '<name>' has an invalid default: <reason>
variable '<name>' has an invalid type: <reason>
metric '<metric>' uses variable '<name>' in its window frame; a variable can't be used in a window frame bound
semantic view '<view>': variable '<name>' has type <type>; a variable can't be a list, array, STRUCT, MAP, UNION, VARIANT or JSON
semantic view '<view>': variable '<name>' does not bind: <DuckDB error>
Cause and fix, in the same order:
VARIABLES ()lists no variable. Declare one, or leave the clause out.Two variables have the same name, compared the way DuckDB compares identifiers (case-insensitively, quoted or not), so
kandKcollide. Rename one.A variable has the name of a fact, dimension or metric (
<kind>says which). Rename the variable.The default is not one expression a query can evaluate.
<reason>says why: it is empty, holds a;, holds a subquery, or holds a prepared-statement parameter. Write a single expression. To supply a value at run time, set the variable in the query instead (see Variables).The type is not one type.
<reason>says why: its brackets do not nest, or it holds a;, a subquery or a prepared-statement parameter. The type is written into a cast wherever the variable is read, so it can’t carry more SQL. Write a single DuckDB type, such asDECIMAL(10, 2).A window metric’s frame bound (
ROWS BETWEEN n PRECEDING AND CURRENT ROW) names a variable. Write the bound as a number.The variable’s type is nested or semi-structured, which Snowflake also refuses. Use a scalar type.
CREATEbinds each variable on its own, and DuckDB could not bind this one. The rest of the message is DuckDB’s error: usually the type does not exist (Type with name NOT_A_TYPE does not exist), or the default reads a column (Referenced column "amount" was not found), which a default cannot do. Use an existing type, and read columns in the member expressions instead.
-- This will fail: "semantic view 'v': variable 'k' does not bind:
-- Binder Error: Referenced column "amount" was not found ..."
VARIABLES (k INTEGER DEFAULT amount)
-- Fix: give the variable a value, and read the column in the member
VARIABLES (k INTEGER DEFAULT 1)
METRICS (sales.n AS SUM(amount * k))
A VARIABLES entry that does not follow name [type] [{DEFAULT | :=} <expr>] [COMMENT '...'] is refused while the statement is parsed:
Expected a variable name at the start of '<entry>': a variable is 'name [type] [DEFAULT <expr>] [COMMENT '...']'.
Variable '<name>' has two defaults; give one.
Expected an expression after the default of variable '<name>'.
Unexpected '<text>' after the comment of variable '<name>'; COMMENT comes last.
A variable’s name is one identifier, with no table alias and no quotes around it as a string (o.v and 'v' are refused). DEFAULT and := are the same keyword, so an entry takes one of them, once, with an expression after it, and COMMENT ends the entry.
CREATE SEMANTIC VIEW ... FROM YAML also refuses a variable that GET_DDL could not write back as it was declared:
variable '<name>' holds a SQL comment marker, which CREATE would drop
variable '<name>' does not read back from GET_DDL as written ('<entry>'); a type or default can't hold surrounding whitespace, or a DEFAULT, := or COMMENT of its own outside brackets
Fix: Remove the comment from the data_type or default, and write each as one type or one expression. See Variable.
Graph validation errors¶
Changed in version 0.14.0: CREATE now also rejects a table that cannot be reached from the base
table (whether or not the view has a RELATIONSHIPS clause), a YAML
relationship without fk_columns, two relationships with the same name,
and a member qualified by an undeclared alias in a single-table view. Each of
these used to be accepted and failed later, at query time, or silently used
the first relationship with a repeated name. Views stored by earlier versions
keep loading.
table '<alias>' cannot reference itself
cycle detected in relationships: <alias1> -> <alias2> -> <alias1>
diamond: '<alias>' is reachable from multiple tables ('<from1>', '<from2>');
the join path is ambiguous. Declare the target under a second table alias
so it is joined once per path.
orphan table '<alias>' is not connected by any relationship; did you mean '<suggestion>'?
base table '<alias>' (the first table in TABLES) is not connected by any
relationship to the other tables ('<alias>', ...); declare a relationship that
reaches it, or list a connected table first
table '<alias>' is not reachable from the base table '<alias>' (the first table
in TABLES) through any chain of relationships; unreachable: '<alias>', ...
relationship '<name>' from '<alias>' to '<alias>' declares no foreign-key columns;
the form is 'rel_name AS from_alias(fk_cols) REFERENCES to_alias'
duplicate relationship name '<name>': '<name>' (<from> -> <to>) and '<other>'
(<from> -> <to>) name the same relationship; relationship names must be unique
within a semantic view (compared case-insensitively, quoted or not)
relationships '<name>' and '<other>' to '<alias>' would both be joined as
'<alias>__<name>'; role-playing relationships to one table need names that differ
once quotes are removed and case is folded
unknown source table '<alias>'; did you mean '<suggestion>'?
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: One target table is reached from two different source tables. Naming the relationships does not help; declare the shared table a second time under another alias (for example
s_a AS storesands_b AS stores) so each path has its own copy. Several relationships from the same source table to one target are allowed; that is the role-playing pattern (see How to Model Role-Playing Dimensions).Orphan: Add a relationship that connects the table, or remove it from
TABLES.Not connected / not reachable: Every table must be reachable from the first table in
TABLES. Add the missing relationship, or remove the table. A view that lists several tables but noRELATIONSHIPSat all gets the base-table form of this error.No foreign-key columns: A YAML
joinsentry needsfk_columns(the DDL form always has them).Duplicate relationship name: Two relationships share a name. Names are compared the way DuckDB compares identifiers, so
route,ROUTEand"route"are one name, whichever tables the relationships connect. Rename one of them. Before this check,USINGsilently used the first relationship with the name. Views stored before the check keep loading and keep that behaviour. A quoted name containing a dot ("x.y") is one identifier, a different name from the two-partx.y.Role-playing names sharing an alias: Two relationships from one table to the same target are joined under
<target>__<name>, with the name’s quotes removed and its case folded.x.yand"x.y"are different names but would get the same alias. Rename one of them.Unknown source table: A dimension or metric is qualified by a table alias that
TABLESdoes not declare, such asx.foowhen the only table iso. This applies to single-table views too. Qualify the member with a declared alias, in any case. Write the alias unquoted: a quoted qualifier such as"O"for aliasois accepted only in a single-table view, and a view with several tables rejects it with this error (a known limitation; DuckDB itself treats"O"andoas the same identifier).
Key missing on a relationship target¶
Table '<target>' has no PRIMARY KEY declared but is referenced by FK in
'<from>'. Add PRIMARY KEY (cols) or UNIQUE (cols) to the TABLES clause for
<target>. (v0.10.0: physical-catalog PK auto-inference removed -- see
CHANGELOG.)
Cause: A relationship references a table whose TABLES entry declares neither PRIMARY KEY nor UNIQUE. An explicit column list on the relationship (REFERENCES <target>(<cols>)) does not satisfy the requirement.
Fix: Declare the key on the target table’s TABLES entry: c AS customers PRIMARY KEY (id), or UNIQUE (email) when the relationship joins on a unique column.
Expression references another table’s column¶
semantic view: fact '<name>' references '<alias>.<column>', a column of
table '<alias>', but a fact expression may only reference columns of its
own table ('<own>'). To use a value from another table, define a FACT on
that table and reference the fact by name (e.g. '<alias>.<fact_name>').
The same message is raised for a dimension or metric expression, with fact replaced by the member kind.
Cause: A fact, dimension, or metric expression names a raw column of a different logical table.
Fix: Define a fact on the other table and reference that fact by name. See How to Use FACTS for Reusable Row-Level Logic.
Unknown metric in a derived metric¶
unknown metric '<name>' referenced in derived metric '<derived>'; did you mean '<suggestion>'?.
Available metrics: [<list>]
Cause: A derived metric’s expression names a metric that the view does not declare, often a typo. The did you mean clause appears only when a declared metric’s name is close enough to suggest.
Fix: Correct the name. The error lists every metric in the view.
LABELS on a metric¶
LABELS is not valid on a metric; it applies to facts and dimensions.
Cause: A METRICS entry carries LABELS = (FILTER). Named filters are row-level members, so only facts and dimensions can be labeled.
Fix: Remove LABELS from the metric. To reuse a filter condition, declare it as a fact or dimension with LABELS = (FILTER). See Mark a Named Filter.
Duplicate LABELS¶
Duplicate LABELS annotation in dimensions entry '<entry>'.
Cause: A fact or dimension entry has LABELS both between its name and AS and after its expression.
Fix: Keep one of them. o.is_large LABELS = (FILTER) AS o.amount > 100 is Snowflake’s placement and the one GET_DDL writes.
Annotation before AS¶
Only LABELS may come between the name and 'AS' in facts entry '<entry>'.
Put COMMENT, WITH SYNONYMS, TAG and the other annotations after the expression.
Cause: A fact or dimension entry has COMMENT, WITH SYNONYMS, TAG or a Cortex Analyst clause such as SAMPLE_VALUES between its name and AS. Only LABELS may go there.
Fix: Move the other annotations after the expression: o.is_large LABELS = (FILTER) AS o.amount > 100 COMMENT = 'Large order'.
Cortex Analyst clause in the wrong place¶
IS_ENUM is not valid on a fact; it applies to dimensions.
SAMPLE_VALUES is not valid on a metric; it applies to facts and dimensions.
WITH CORTEX SEARCH SERVICE is not valid at the view level; it applies to dimensions.
Cause: A Cortex Analyst member clause is on an object Snowflake does not allow it on. SAMPLE_VALUES goes on facts and dimensions; IS_ENUM and WITH CORTEX SEARCH SERVICE go on dimensions only. The view-level clauses (MAX_STALENESS, AI_SQL_GENERATION, AI_QUESTION_CATEGORIZATION, AI_VERIFIED_QUERIES, COPY GRANTS) go after the last clause; after a member’s annotations they raise Unexpected text in annotations.
Fix: Move the clause to the kind of object it applies to, or remove it.
WITH EXTENSION¶
WITH EXTENSION is not supported: it is Snowflake's undocumented Cortex Analyst export from GET_DDL. ...
Cause: The DDL ends with WITH EXTENSION (CA = '<json>'). Snowflake’s GET_DDL writes this clause for Cortex Analyst metadata that was set outside the DDL, such as sample values entered in Snowsight. It is not part of Snowflake’s CREATE SEMANTIC VIEW syntax, and its JSON format is not documented, so this extension does not read it.
Fix: Remove the clause. To keep the sample values, write them as SAMPLE_VALUES ('...') on their dimensions and facts (see Cortex Analyst metadata).
MAX_STALENESS out of range¶
MAX_STALENESS is 60 seconds; the minimum is 120 seconds.
MAX_STALENESS '1 fortnight' is not an interval; ...
Cause: MAX_STALENESS (in CREATE, ALTER ... SET or YAML max_staleness) is under Snowflake’s 120-second minimum, or its quoted form is not a count and a unit of seconds, minutes, hours or days.
Fix: Write at least 120 seconds: MAX_STALENESS = 120 or MAX_STALENESS = '2 minutes'.
Aggregate in a dimension or fact¶
semantic view: dimension '<name>' must not contain the aggregate function
'<func>'. A dimension is a row-level value; define a metric for the aggregate.
semantic view: fact '<name>' must not contain the aggregate function
'<func>'. A fact is a row-level value; define a metric for the aggregate.
Cause: A dimension or fact expression calls an aggregate function such as SUM, COUNT, AVG or arg_max. A query groups by a dimension, and a metric aggregates a fact, so neither can hold an aggregate of its own.
Fix: Move the aggregation to the METRICS clause. An aggregate inside a subquery ((SELECT max(t) FROM tiers)) and a windowed aggregate (SUM(o.amount) OVER (PARTITION BY o.region)) are one value per row and are allowed.
Parameter in a member¶
semantic view: dimension '<name>' holds the prepared statement parameter $1,
which has no value inside the view's definition. Use parameters in the WHERE
clause of a SEMANTIC_VIEW(...) query instead.
Cause: A dimension, fact or metric expression (or a window metric’s arguments, ORDER BY or frame) holds a prepared statement parameter: ?, ?1, $1 or $name. A member is expanded inside the view’s own query, where no parameter has a value. The message names fact or metric for those members.
Fix: Write the value into the expression, or filter with a parameter in the query’s WHERE clause. See Pre-Aggregation – WHERE in the Construct, or where_clause.
Circular fact or metric references¶
cycle detected in facts: <name1> -> <name2> -> <name1>
cycle detected in derived metrics: <name1> -> <name2> -> <name1>
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¶
invalid YAML definition for semantic view '<name>': <details>
For example, a definition without a metrics key fails with:
invalid YAML definition for semantic view 'sales': missing field `metrics`
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 against YAML Definition Format. The definition must include tables and both the dimensions and metrics keys (use [] for one of them if the view has none), and at least one of the two must be non-empty.
Query Errors¶
These errors occur at query time, when querying with the SEMANTIC_VIEW(…) construct, semantic_view(), explain_semantic_view(), or standard SQL over the view by name. A standard-SQL query turns into the construct, so after the checks under Standard-SQL query refused it can raise any error in this section; those messages name the construct’s clauses (METRICS, FACTS) or the matching function parameter (where_clause for the query’s WHERE).
Malformed SEMANTIC_VIEW(…)¶
Added in version 0.16.0.
Parser Error: expected DIMENSIONS, METRICS, FACTS, WHERE or VARIABLES after the view name in SEMANTIC_VIEW(...), got: ,
Parser Error: METRICS given twice in SEMANTIC_VIEW(...)
Parser Error: METRICS needs at least one item
Cause: The construct’s clauses are not where the grammar expects them. The usual slips are a comma after the view name (the construct has none), a clause written twice, and a clause with no items.
Fix: Write the view name, then each clause at most once, each with at least one item: SEMANTIC_VIEW(shop DIMENSIONS region METRICS revenue, order_count). To add items, extend the one clause rather than repeating it.
Parameter outside WHERE¶
Added in version 0.16.0.
Parser Error: prepared statement parameters are only supported in the WHERE clause of SEMANTIC_VIEW(...)
Cause: A prepared-statement parameter (?, $1, $name) appears in DIMENSIONS, METRICS or FACTS.
Fix: Use parameters only in the construct’s WHERE and in the values of its VARIABLES (see Variables). To choose the view, the dimensions or the metrics at run time, use semantic_view(), whose arguments can all be bound.
Two columns with the same name¶
Added in version 0.16.0.
semantic view '<view>': two columns of the query are named '<name>'; give one of them another name with AS
Cause: Two items produce the same column name, through an alias or because an alias repeats a member’s name.
Fix: Give one of them another alias.
Variables in a query¶
Added in version 0.18.0.
semantic view '<view>': variable '<name>' has no default, so the query must set it: VARIABLES <name> = <value>
semantic view '<view>' has no variable '<name>'. Did you mean '<closest>'?
Binder Error: semantic_view: variables must be a struct of values by name, e.g. variables := {'min_amount': 2000}, not <type>
Parser Error: VARIABLES comes last in SEMANTIC_VIEW(...), after <CLAUSE>
Parser Error: expected 'name = value' in VARIABLES, got: <text>
Parser Error: a variable's value can't be a query
Binder Error: semantic_view: variable '<name>' is set to a <type>; a variable can't be a list, array, STRUCT, MAP, UNION, VARIANT or JSON
Cause and fix, in the same order:
The view declares a variable with no default, and the query does not set it. Every query of the view must set such a variable, even one that reads no member that uses it, as in Snowflake. Set it in the construct’s
VARIABLESor invariables := {...}. A standard-SQL query cannot set variables, so query such a view withSEMANTIC_VIEW(...)instead, or give the variable a default.The query sets a variable the view does not declare. The hint names the closest declared variable, when one is close. Check the spelling against DESCRIBE SEMANTIC VIEW.
variablesis not a struct with named fields, such asrow(1). Pass{'name': value, ...}.explain_semantic_viewreports the same error under its own name.A clause follows
VARIABLESin the construct. MoveVARIABLESto the end, afterWHERE.An item in
VARIABLESis not an assignment. Writename = valueorname => value.A value is a
SEMANTIC_VIEW(...)query. A variable’s value cannot be a query. A plain subquery as a value, such as(SELECT 'x'), gets DuckDB’s ownTable function cannot contain subqueries. Compute the value first, and pass it as a value or a prepared-statement parameter.The value is nested or semi-structured, which a variable can’t be, even one declared with no type. Pass a scalar value.
Expression item errors¶
Added in version 0.16.0.
An expression item is checked against the rules for its clause. Each message quotes the expression as you wrote it:
'<name>' in '<expression>' is not a dimension, fact or metric of semantic view '<view>'; an expression item can only read the view's members
'<expression>' uses '<a>' and '<b>', which belong to different tables; the dimensions and facts of <item> must belong to one table
'<expression>' in DIMENSIONS holds the aggregate function '<function>'; an aggregate goes in METRICS
'<name>' in '<expression>' is a fact; in METRICS a dimension or fact can only be used inside an aggregate
'<name>' in '<expression>' is a metric; an ad-hoc aggregate can only use dimensions and facts
'<expression>' refers to no dimension or fact; an ad-hoc aggregate must use at least one. To count rows, declare a metric on a table, such as '<alias>.order_count AS COUNT(*)', and query that metric
'<expression>' holds a window function; a query item cannot, so declare a window metric in the semantic view
'<expression>' holds a subquery; a query item cannot, only the WHERE clause can
Cause and fix, in the same order:
The expression names a column the view does not declare, such as a raw table column. An expression reads only the view’s members. Declare the column as a dimension or fact, or use the member that already wraps it.
A
DIMENSIONSorFACTSexpression, or one aggregate inMETRICS, mixes members of two tables. Its members must belong to one table, so query them as two items.An aggregate in
DIMENSIONSorFACTS. Move the item toMETRICS.A dimension or fact used bare in
METRICS. Wrap it in an aggregate (max(amount)), or move it toDIMENSIONS.An aggregate over a metric, as in
sum(revenue). A metric is already aggregated; use it as it is, or aggregate the fact it is built from.An aggregate that names no member, such as
count(*), has no table to be computed over. Declare it as a metric in the view (o.order_count AS COUNT(*)) and query that.A window function. Declare a window metric.
A subquery. Filter with a subquery in
WHEREinstead, or declare a member over it.
Standard-SQL query refused¶
Added in version 0.17.0.
A standard-SQL query over a semantic view follows Snowflake’s rules for that form. A query that breaks one is refused before it becomes a SEMANTIC_VIEW(...) query, with an error naming the view:
semantic view '<view>': metric '<name>' must be passed to AGG, e.g. AGG(<name>)
semantic view '<view>': dimension '<name>' must appear in GROUP BY
semantic view '<view>': '<name>' must be passed to an aggregate or appear in GROUP BY
semantic view '<view>': HAVING may refer only to metrics passed to AGG or another aggregate, not '<expression>'; filter dimensions in WHERE
semantic view '<view>': AGG takes one metric, e.g. AGG(revenue)
semantic view '<view>': GROUP BY position <n> is not in the SELECT list
semantic view '<view>': SELECT * is not supported in a query over a semantic view; name the dimensions, metrics and facts to return
semantic view '<view>' cannot be joined, pivoted or read alongside other tables; query it on its own (in a subquery or CTE) and join the result
semantic view '<view>': window functions are not supported in a query over a semantic view; query it in a subquery and apply the window to the result
semantic view '<view>': QUALIFY is not supported in a query over a semantic view; query it in a subquery and filter the result
semantic view '<view>': GROUPING SETS, ROLLUP and CUBE are not supported in a query over a semantic view
semantic view '<view>': sampling is not supported in a query over a semantic view; query it in a subquery and sample the result
semantic view '<view>': a column alias list is not supported on a semantic view; alias the SELECT items instead
semantic view '<view>': '<expression>' refers to '<table>' of an enclosing query; correlated references are not supported in a query over a semantic view (if '<table>' is meant as the view's own table, give the enclosing one another alias)
Cause and fix, in the same order:
A metric named bare in
SELECT,ORDER BYorHAVING. A metric is already aggregated: pass it toAGG. InHAVINGaSELECTalias that repeats a metric’s name still names the metric, so writeHAVING AGG(revenue) > 400.A dimension in
SELECTorORDER BYthat is not grouped. Add it toGROUP BY, or writeGROUP BY ALL.A fact or name that is neither grouped nor aggregated, in a query with a
GROUP BY(SELECT region, amount ... GROUP BY region) or inside an expression with an aggregate (AGG(revenue) + amount). Aggregate the fact, or group by it. A misspelled member name gives this error too.HAVINGover a dimension or fact. Filter those inWHERE, which runs before the metrics are computed.AGGwith more than one argument, or withDISTINCT,FILTERorORDER BYinside it. Pass one metric.GROUP BYa position past the end of theSELECTlist. Correct the number.SELECT *. Name the dimensions and metrics, or useSELECT * FROM SEMANTIC_VIEW(...).The rest are refused in the query block that reads the view: a join or
FROMlist with other tables,PIVOT, a window function,QUALIFY, grouping sets, sampling, a column alias list (FROM v AS s(a, b)), or a qualified reference to a table of an enclosing query. Query the view in a subquery or CTE, then join, window, filter or sample its result.
In a query with no GROUP BY, a SELECT item that is neither grouped nor aggregated is a fact. Alongside an AGG it raises Cannot combine facts and metrics, which is also what a misspelled member name next to an AGG gives there.
A name in FROM that is a table, a view, a CTE in scope, or a Python DataFrame or relation is read as that, not as a semantic view, and a name that is none of these gets DuckDB’s own Catalog Error: Table with name ... does not exist!.
View not found¶
Semantic view '<name>' not found. Did you mean '<suggestion>'?
Available views: [<list>].
Run SHOW 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 one of DIMENSIONS, METRICS or FACTS
(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 (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.
Since v0.14.0 a metric is normally aggregated from its own table, where there are no NULL-extended rows, so this error is rare: it is raised only for the query shapes that still use a base-table LEFT JOIN (for example a dimension with no source table in a definition stored by an older version).
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 Diagnose and Fix Fan Traps for detailed solutions: remove the problematic dimension, use a metric from the same table as the dimension, or restructure the view.
Fact reached across a fan-out¶
semantic view '<view>': fan trap detected -- '<metric>' (table '<table>')
references the fact '<fact>' on table '<fact_table>', and relationship
'<rel>' fans out on the way there, so joining it would multiply '<metric>'s
rows. Reference a fact on a table reachable without fanning out, or define
the fact on '<table>'.
Cause: A metric references a fact on a table that sits on the “many” side of a relationship from the metric’s table (for example, a metric on orders using a fact on line_items). Joining that table would repeat each of the metric’s rows once per child row.
Fix: Move the fact to the metric’s own table, reference a fact on a parent (many-to-one) table instead, or define the metric on the child table. See How to Use FACTS for Reusable Row-Level Logic.
Ambiguous dimension path¶
semantic view '<view>': dimension '<dim>' is ambiguous -- table '<table>'
is reached via multiple relationships: [<rel1>, <rel2>]. Give every metric
in the query a USING that names one of them, or use a dimension from a
non-ambiguous table. If every metric already has one, this query cannot be
split by path (two window metrics, or metrics beside a semi-additive one):
query the metrics separately.
Cause: A dimension comes from a table reachable via multiple named relationships (role-playing pattern), and a metric in the query has no USING clause that selects one path to it (or the query has no metrics). A metric on a table further from the dimension, such as a child of the table that holds the relationships, cannot name a path at all, because a USING relationship must start at the metric’s own table. The same message appears when every metric names a path but they name different ones in a query that is not grouped per path: two window metrics, or metrics beside a semi-additive metric whose NON ADDITIVE BY dimension is not queried. A window metric names its path through its inner metric.
Fix: See How to Model Role-Playing Dimensions. Give each metric USING (<rel_name>), for example by writing f.departures USING (<rel_name>) AS f.flight_count over a plain metric, or use a dimension from a table that is not a role-playing target.
Changed in version 0.18.0: Every metric needs its own USING. A metric without one used to take the
path of a co-queried metric that had one.
A dimension on a table reached only through the role-playing table, such as
regions referenced by airports, reports the same problem in this form:
semantic view '<view>': dimension '<dim>' is ambiguous -- its table '<table>'
is reachable only through the role-playing table '<rp_table>', which is
joined via multiple relationships: [<rel1>, <rel2>]. Query it with metrics
that each name one of them in their USING (a metric on '<rp_table>' itself
cannot), ...
It has the same causes and fixes. The dimension takes its path from the
metrics, so a query with no metrics, or with a metric declared on the
role-playing table (whose USING cannot start there), has no path to give
it. When every metric names a path, the region follows it: departures by
region groups by the departure airport’s region.
Changed in version 0.18.0: A dimension past the role-playing table used to be refused even when every metric named a path to it.
Ambiguous fact or metric on a role-playing table¶
Changed in version 0.14.0: These queries used to return the numbers of whichever relationship was declared first.
semantic view '<view>': '<member>' is ambiguous -- it references fact '<fact>'
on table '<table>', which requires the role-playing table '<table>', joined via
multiple relationships: [<rel1>, <rel2>]. A metric over a fact on '<table>'
itself must name exactly one of them with USING; a dimension, or a fact on a
table reached only through '<table>', has no way to pick a role.
semantic view '<view>': metric '<metric>' is ambiguous -- it aggregates table
'<table>', which requires the role-playing table '<table>', joined via
multiple relationships: [<rel1>, <rel2>]. A metric on that table cannot name a
role (USING relationships must originate from the metric's own table); declare
it on the referencing table with USING instead, e.g.
<table>.<metric> USING (<relationship>) AS SUM(<fact>).
Cause: The first form: a metric, dimension, or fact reaches a fact on a role-playing table (or on a table reached only through one), and nothing says which relationship to read it through. The second form: a metric is declared on the role-playing table itself, where USING cannot be attached. When the relationships fan out, the second case raises fan trap detected instead. If the role-playing table is the view’s base table (declared first in TABLES), a metric on it is answered when it is queried without dimensions, alongside only other base-table metrics, and with a filter (if any) that names only base-table members. A dimension, filter, co-queried metric or NON ADDITIVE BY dimension on another table brings this error back. Grouping by a dimension on the base table itself, or a NON ADDITIVE BY on one, is rejected too, with the dimension ... is ambiguous error (a known limitation).
Fix: Declare the metric on the referencing table and give it a USING that names one relationship, for example f.dep_elev USING (dep_airport) AS SUM(a.elev). See Aggregating a Fact on the Role-Playing Table.
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 METRICS (the metrics := [...] list), or used in an expression item.
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 FACTS (the facts := [...] list), or used in an expression item.
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 (facts := [...] or metrics := [...]), not both.
Cause: The query includes both FACTS and METRICS (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.
Cannot query facts with dimensions¶
Added in version 0.18.0.
semantic view '<view>': querying FACTS with DIMENSIONS is not supported. List the dimensions in FACTS
for one row per source row, or the facts in DIMENSIONS for one row per distinct value.
Cause: The query lists facts in FACTS and dimensions in DIMENSIONS (facts := [...] and dimensions := [...]). As in Snowflake, a query reads members either row by row or grouped, not both.
Fix: For one row per source row, move the dimensions into FACTS: a dimension listed there is read row by row. For one row per distinct value, move the facts into DIMENSIONS: a fact listed there is grouped on. See Combine Facts with Dimensions.
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.
Changed in version 0.17.0: Two tables that neither reaches are accepted when a third table the query
reads reaches both: a fact on orders with a dimension on customers
and one on products, which orders both references.
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 table of the query reaches every other without fanning out – a chain of many-to-one relationships is fine, however long, and so are two tables that one the query reads both references.
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.
Query time limit exceeded¶
Added in version 0.15.0.
INTERRUPT Error: Query exceeded maximum execution time
Cause: The session has a per-query time limit (SET max_execution_time, in milliseconds), and the query ran past it. This is DuckDB’s own error. It applies to semantic-view queries and to the SHOW and DESCRIBE commands that report member data types (see Time Limits).
Fix: Raise the limit, or turn it off for the session:
SET max_execution_time = 60000; -- 60 seconds
RESET max_execution_time; -- no limit
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.
Name Resolution and Catalog Errors¶
These errors come from how a view name is resolved to a schema, and from which database holds the semantic view catalog.
Unqualified name that is not on the search path¶
semantic view '<name>' does not exist on the search path. It exists in
schemas <schemas>, none of which are on the current search path (<path>).
Qualify the reference as <schema>.<name>, or add the schema to search_path.
Cause: An unqualified reference resolves through the session’s search_path, the same rule DuckDB applies to an unqualified table name. A view of this name exists, but only in schemas that are not on the path – so by that rule it is not visible from here. DuckDB would report a plain “does not exist”; this message says where the view actually is instead, because a bare not-found is confusing for something SHOW SEMANTIC VIEWS plainly lists.
This applies to reads and writes alike, and IF EXISTS does not suppress it: that clause means “do not complain if the view is absent”, and a view sitting off the path is not absent. Suppressing it would let a DROP silently remove one of several same-named views.
Fix: Either qualify the reference (DROP SEMANTIC VIEW analytics.sales, SEMANTIC_VIEW(analytics.sales METRICS ...)) or put the schema on the path (SET search_path = 'analytics'). When several schemas hold the name, the first one on the path wins.
Note: A view that is the only one of its name resolves whether or not its schema is on the path, so this error only appears once a second view shares the name.
DDL issued from an attached database¶
semantic_views: semantic-view DDL was issued against database '<db>', but
the semantic view catalog lives in a different database. Semantic views are
single-catalog: manage them from the database the extension was loaded
into, without USE-ing into an attached database.
Cause: The session ran USE on an attached database, then issued CREATE, ALTER, or DROP SEMANTIC VIEW. Semantic view definitions are stored only in the database the extension was loaded into.
Fix: Switch back to that database (USE memory, or the name of your file database) before running semantic-view DDL. A view body can still read tables from an attached database by qualifying them (TABLES (o AS other.main.orders ...)). See Attached Databases (Single-Catalog).
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.* (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.