# How to Troubleshoot Common Semantic Model Configuration Errors in Dat

> Troubleshoot common Dat semantic model configuration errors with pre-build, model-level, and runtime checks. Catch duplicate names and invalid SQL before deployment.

- Repository: [Junjie.M/dat](https://github.com/junjiem/dat)
- Tags: how-to-guide
- Published: 2026-03-05

---

**Validate your Dat semantic models through the pre-build, model-level, and runtime checks to catch duplicate names, invalid SQL syntax, and database-specific errors before deployment.**

Dat’s semantic model configuration is validated at multiple layers during project build and runtime. Understanding where these checks occur—inside `PreBuildValidator` and `SemanticModelUtil`—allows you to quickly pinpoint and resolve configuration errors. This guide walks you through the validation pipeline, common error patterns, and a systematic troubleshooting workflow based on the junjiem/dat source code.

## Understanding the Validation Pipeline

Dat validates semantic models through three distinct phases: project pre-build, model-level static analysis, and SQL generation with runtime execution. Each phase catches different categories of errors.

### Project Pre-Build Validation

During the build phase, `ai.dat.boot.PreBuildValidator.validateSemanticModelSqls` (lines 29-41 in [`dat-sdk/src/main/java/ai/dat/boot/PreBuildValidator.java`](https://github.com/junjiem/dat/blob/main/dat-sdk/src/main/java/ai/dat/boot/PreBuildValidator.java)) parses the generated SQL and runs a lightweight validation query (`WITH … SELECT 1`) against the target database. This ensures the model compiles and that database connectivity is functional.

### Model-Level Validation

The `ai.dat.core.utils.SemanticModelUtil` class provides static validation methods used throughout the codebase. `validateSemanticModels` and `validateSemanticModel` (lines 34-60 in [`dat-core/src/main/java/ai/dat/core/utils/SemanticModelUtil.java`](https://github.com/junjiem/dat/blob/main/dat-core/src/main/java/ai/dat/core/utils/SemanticModelUtil.java)) check for duplicate model names, verify the model string starts with `SELECT`, and forbid trailing semicolons.

### SQL Generation and Runtime Execution

When generating the final query, `SemanticModelUtil.semanticModelSql` (lines 93-141) builds the SQL by concatenating entity, dimension, and measure expressions, then parses the user-provided model portion with Calcite. Runtime errors surface when `DatabaseAdapter.executeQuery` (called from `PreBuildValidator` at lines 66-71) executes the generated SQL against the configured database.

## Common Semantic Model Configuration Errors and Solutions

Most configuration errors fall into six categories, each with distinct symptoms and resolution steps.

### Duplicate Model Names

**Symptom:** `IllegalArgumentException: There are duplicate semantic model names: …`

**Root Cause:** The `validateSemanticModels` method uses a `groupingBy` operation to collect duplicate names across all models defined in your YAML files.

**Solution:** Ensure each model’s `name` field is unique within the project scope (typically under `agents[].semantic_models`). Run a quick check with:

```bash
grep -R "name:" src/**/*.yaml | sort | uniq -c | grep -v " 1 "

```

### Invalid SELECT Statement Format

**Symptom:** `IllegalArgumentException: The model of the semantic model 'X' must be a SELECT statement`

**Root Cause:** `validateSemanticModel` checks `sql.trim().toUpperCase().startsWith("SELECT")`. Any CTEs without a leading `SELECT` or non-query statements fail this check.

**Solution:** Prepend `SELECT` to the model definition or wrap subqueries in a `SELECT … FROM (…)` structure. Ensure no leading whitespace or comments precede the `SELECT` keyword.

### Trailing Semicolon Errors

**Symptom:** `IllegalArgumentException: … cannot contain ';'`

**Root Cause:** A regex `.*\\s*;\\s*$` in `validateSemanticModel` detects trailing semicolons that could break SQL concatenation during generation.

**Solution:** Remove any trailing `;` from the `model` string in your YAML configuration. The parser automatically handles statement termination.

### Calcite Parse Failures

**Symptom:** `SqlParseException: …`

**Root Cause:** `semanticModelSql` parses each `entity.expr`, `dimension.expr`, and `measure.expr` using `SqlParserWrapper` (Calcite). Invalid SQL syntax or dialect-specific functions trigger this exception.

**Solution:** Verify each expression is valid SQL for your target dialect (e.g., PostgreSQL). Test expressions individually in your database client before adding them to the model. Check that function names and syntax match the adapter’s capabilities.

### Database Execution Errors

**Symptom:** `SQLException: column … does not exist` or similar database-specific messages

**Root Cause:** `PreBuildValidator.validateSemanticModelSqls` executes a validation query (`SELECT 1 FROM <CTE> WHERE 1=0`) against the actual database. Missing tables, columns, or unsupported functions surface here.

**Solution:** Confirm all referenced columns and tables exist in the underlying source tables. Verify that any time-granularity functions are supported by your configured adapter. Check database connectivity and credentials in the `db.provider` configuration.

### Time-Granularity Misconfiguration

**Symptom:** Errors like "Unsupported time granularity"

**Root Cause:** `semanticModelSql` calls `semanticAdapter.applyTimeGranularity` to handle `dimension.type=TIME` configurations. Invalid `typeParams.timeGranularity` values cause failures.

**Solution:** Ensure the `dimension.type` is set to `TIME` and that `typeParams.timeGranularity` matches a supported value (e.g., `day`, `hour`, `minute`). Consult your specific `SemanticAdapter` implementation for supported granularities.

## Step-by-Step Troubleshooting Workflow

Follow this systematic approach to isolate and resolve semantic model configuration errors:

1. **Run a dry build** – Execute `dat build` (or the Maven compile step) to trigger `PreBuildValidator`. Capture the full exception stack trace.

2. **Locate the offending model** – The error message includes the model name; open the corresponding YAML file under `agents[].semantic_models`.

3. **Inspect the `model` field** – Verify it starts with `SELECT` and contains no trailing semicolons.

4. **Validate each expression** – For every `entity`, `dimension`, or `measure`, copy the `expr` into a SQL client using the same dialect and execute it independently.

5. **Check for duplicate names** – Run a quick grep to identify naming collisions: `grep -R "name:" src/**/*.yaml | sort | uniq -c | grep -v " 1 "`.

6. **Confirm DB connectivity** – Ensure the `db.provider` configuration points to a reachable database with valid credentials.

7. **Rerun the build** – After fixes, rebuild the project. Successful completion indicates the semantic model is valid.

## Programmatic Validation Examples

You can also validate models programmatically using Dat’s utility classes.

### Detecting Duplicate Model Names

```java
List<SemanticModel> models = // loaded from YAML
SemanticModelUtil.validateSemanticModels(models);   
// throws IllegalArgumentException if duplicates exist

```

**Stack trace indicator:** `There are duplicate semantic model names: foo, bar` → rename duplicated entries.

### Manually Testing Generated SQL

```java
// Using a PostgreSQL adapter
SemanticAdapter pgAdapter = new PostgreSqlSemanticAdapter();
SemanticModel model = // loaded from YAML
String sql = SemanticModelUtil.semanticModelSql(pgAdapter, model);
System.out.println(sql);      // review the full CTE-wrapped query

```

Copy the printed SQL into `psql` or your DB client. Execution failures indicate problems in expressions or underlying tables.

### Using PreBuildValidator in Tests

```java
PreBuildValidator validator = new PreBuildValidator();
try {
    validator.validate(project);   // triggers all semantic model checks
} catch (ValidationException e) {
    System.err.println(e.getMessage()); // detailed list of offending models
}

```

## Summary

- **Validation occurs in three phases**: pre-build (`PreBuildValidator`), model-level (`SemanticModelUtil`), and runtime SQL execution.
- **Common errors include**: duplicate model names, missing `SELECT` keywords, trailing semicolons, Calcite parse failures, and database execution errors.
- **Key files to inspect**: [`SemanticModelUtil.java`](https://github.com/junjiem/dat/blob/main/SemanticModelUtil.java) for static validation logic and [`PreBuildValidator.java`](https://github.com/junjiem/dat/blob/main/PreBuildValidator.java) for build-time SQL verification.
- **Systematic troubleshooting**: Run a dry build, inspect the `model` field format, validate individual expressions in your SQL client, and confirm database connectivity.

## Frequently Asked Questions

### How do I fix "duplicate semantic model names" errors?

This error originates in `SemanticModelUtil.validateSemanticModels` when the `groupingBy` operation detects identical `name` values across your YAML configurations. To resolve, ensure each model has a unique `name` field within the project scope, typically defined under `agents[].semantic_models`. Use `grep` to scan for duplicates across your YAML files.

### Why does my model fail with "must be a SELECT statement"?

The `validateSemanticModel` method in [`SemanticModelUtil.java`](https://github.com/junjiem/dat/blob/main/SemanticModelUtil.java) enforces that every model string must start with `SELECT` (case-insensitive after trimming). This check prevents injection of non-query statements. If your model uses CTEs or subqueries, ensure the outermost statement is a `SELECT`, or wrap the entire logic in `SELECT * FROM (...)`.

### How can I validate semantic models without running a full build?

You can programmatically validate models using `SemanticModelUtil.validateSemanticModels(List<SemanticModel>)` for static checks, or instantiate `PreBuildValidator` to execute the full validation pipeline including SQL generation and database connectivity tests. This approach is useful for unit testing or CI/CD pipelines where you want fast feedback on configuration changes.