databricks-aibi-dashboards

AI/BI Dashboard Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "databricks-aibi-dashboards" with this command: npx skills add databricks-solutions/ai-dev-kit/databricks-solutions-ai-dev-kit-databricks-aibi-dashboards

AI/BI Dashboard Skill

Create Databricks AI/BI dashboards (formerly Lakeview dashboards). Follow these guidelines strictly.

CRITICAL: MANDATORY VALIDATION WORKFLOW

You MUST follow this workflow exactly. Skipping validation causes broken dashboards.

┌─────────────────────────────────────────────────────────────────────┐ │ STEP 1: Get table schemas via get_table_details(catalog, schema) │ ├─────────────────────────────────────────────────────────────────────┤ │ STEP 2: Write SQL queries for each dataset │ ├─────────────────────────────────────────────────────────────────────┤ │ STEP 3: TEST EVERY QUERY via execute_sql() ← DO NOT SKIP! │ │ - If query fails, FIX IT before proceeding │ │ - Verify column names match what widgets will reference │ │ - Verify data types are correct (dates, numbers, strings) │ ├─────────────────────────────────────────────────────────────────────┤ │ STEP 4: Build dashboard JSON using ONLY verified queries │ ├─────────────────────────────────────────────────────────────────────┤ │ STEP 5: Deploy via create_or_update_dashboard() │ └─────────────────────────────────────────────────────────────────────┘

WARNING: If you deploy without testing queries, widgets WILL show "Invalid widget definition" errors!

Available MCP Tools

Tool Description

get_table_details

STEP 1: Get table schemas for designing queries

execute_sql

STEP 3: Test SQL queries - MANDATORY before deployment!

get_best_warehouse

Get available warehouse ID

create_or_update_dashboard

STEP 5: Deploy dashboard JSON (only after validation!)

get_dashboard

Get dashboard details by ID, or list all dashboards (omit dashboard_id)

delete_dashboard

Move dashboard to trash

publish_dashboard

Publish (publish=True ) or unpublish (publish=False ) a dashboard

Implementation Guidelines

  1. DATASET ARCHITECTURE (STRICT)
  • One dataset per domain (e.g., orders, customers, products)

  • Exactly ONE valid SQL query per dataset (no multiple queries separated by ; )

  • Always use fully-qualified table names: catalog.schema.table_name

  • SELECT must include all dimensions needed by widgets and all derived columns via AS aliases

  • Put ALL business logic (CASE/WHEN, COALESCE, ratios) into the dataset SELECT with explicit aliases

  • Contract rule: Every widget fieldName must exactly match a dataset column or alias

  1. WIDGET FIELD EXPRESSIONS

CRITICAL: Field Name Matching Rule The name in query.fields MUST exactly match the fieldName in encodings . If they don't match, the widget shows "no selected fields to visualize" error!

Correct pattern for aggregations:

// In query.fields: {"name": "sum(spend)", "expression": "SUM(spend)"}

// In encodings (must match!): {"fieldName": "sum(spend)", "displayName": "Total Spend"}

WRONG - names don't match:

// In query.fields: {"name": "spend", "expression": "SUM(spend)"} // name is "spend"

// In encodings: {"fieldName": "sum(spend)", ...} // ERROR: "sum(spend)" ≠ "spend"

Allowed expressions in widget queries (you CANNOT use CAST or other SQL in expressions):

For numbers:

{"name": "sum(revenue)", "expression": "SUM(revenue)"} {"name": "avg(price)", "expression": "AVG(price)"} {"name": "count(orders)", "expression": "COUNT(order_id)"} {"name": "countdistinct(customers)", "expression": "COUNT(DISTINCT customer_id)"} {"name": "min(date)", "expression": "MIN(order_date)"} {"name": "max(date)", "expression": "MAX(order_date)"}

For dates (use daily for timeseries, weekly/monthly for grouped comparisons):

{"name": "daily(date)", "expression": "DATE_TRUNC("DAY", date)"} {"name": "weekly(date)", "expression": "DATE_TRUNC("WEEK", date)"} {"name": "monthly(date)", "expression": "DATE_TRUNC("MONTH", date)"}

Simple field reference (for pre-aggregated data):

{"name": "category", "expression": "category"}

If you need conditional logic or multi-field formulas, compute a derived column in the dataset SQL first.

  1. SPARK SQL PATTERNS
  • Date math: date_sub(current_date(), N) for days, add_months(current_date(), -N) for months

  • Date truncation: DATE_TRUNC('DAY'|'WEEK'|'MONTH'|'QUARTER'|'YEAR', column)

  • AVOID INTERVAL syntax - use functions instead

  1. LAYOUT (6-Column Grid, NO GAPS)

Each widget has a position: {"x": 0, "y": 0, "width": 2, "height": 4}

CRITICAL: Each row must fill width=6 exactly. No gaps allowed.

Recommended widget sizes:

Widget Type Width Height Notes

Text header 6 1 Full width; use SEPARATE widgets for title and subtitle

Counter/KPI 2 3-4 NEVER height=2 - too cramped!

Line/Bar chart 3 5-6 Pair side-by-side to fill row

Pie chart 3 5-6 Needs space for legend

Full-width chart 6 5-7 For detailed time series

Table 6 5-8 Full width for readability

Standard dashboard structure:

y=0: Title (w=6, h=1) - Dashboard title (use separate widget!) y=1: Subtitle (w=6, h=1) - Description (use separate widget!) y=2: KPIs (w=2 each, h=3) - 3 key metrics side-by-side y=5: Section header (w=6, h=1) - "Trends" or similar y=6: Charts (w=3 each, h=5) - Two charts side-by-side y=11: Section header (w=6, h=1) - "Details" y=12: Table (w=6, h=6) - Detailed data

  1. CARDINALITY & READABILITY (CRITICAL)

Dashboard readability depends on limiting distinct values:

Dimension Type Max Values Examples

Chart color/groups 3-8 4 regions, 5 product lines, 3 tiers

Filters 4-10 8 countries, 5 channels

High cardinality Table only customer_id, order_id, SKU

Before creating any chart with color/grouping:

  • Check column cardinality (use get_table_details to see distinct values)

  • If >10 distinct values, aggregate to higher level OR use TOP-N + "Other" bucket

  • For high-cardinality dimensions, use a table widget instead of a chart

  1. WIDGET SPECIFICATIONS

Widget Naming Convention (CRITICAL):

  • widget.name : alphanumeric + hyphens + underscores ONLY (no spaces, parentheses, colons)

  • frame.title : human-readable name (any characters allowed)

  • widget.queries[0].name : always use "main_query"

CRITICAL VERSION REQUIREMENTS:

Widget Type Version

counter 2

table 2

filter-multi-select 2

filter-single-select 2

filter-date-range-picker 2

bar 3

line 3

pie 3

text N/A (no spec block)

Text (Headers/Descriptions):

  • CRITICAL: Text widgets do NOT use a spec block!

  • Use multilineTextboxSpec directly on the widget

  • Supports markdown: # , ## , ### , bold , italic

  • CRITICAL: Multiple items in the lines array are concatenated on a single line, NOT displayed as separate lines!

  • For title + subtitle, use separate text widgets at different y positions

// CORRECT: Separate widgets for title and subtitle { "widget": { "name": "title", "multilineTextboxSpec": { "lines": ["## Dashboard Title"] } }, "position": {"x": 0, "y": 0, "width": 6, "height": 1} }, { "widget": { "name": "subtitle", "multilineTextboxSpec": { "lines": ["Description text here"] } }, "position": {"x": 0, "y": 1, "width": 6, "height": 1} }

// WRONG: Multiple lines concatenate into one line! { "widget": { "name": "title-widget", "multilineTextboxSpec": { "lines": ["## Dashboard Title", "Description text here"] // Becomes "## Dashboard TitleDescription text here" } }, "position": {"x": 0, "y": 0, "width": 6, "height": 2} }

Counter (KPI):

  • version : 2 (NOT 3!)

  • widgetType : "counter"

  • Percent values must be 0-1 in the data (not 0-100)

Two patterns for counters:

Pattern 1: Pre-aggregated dataset (1 row, no filters)

  • Dataset returns exactly 1 row

  • Use "disaggregated": true and simple field reference

  • Field name matches dataset column directly

{ "widget": { "name": "total-revenue", "queries": [{ "name": "main_query", "query": { "datasetName": "summary_ds", "fields": [{"name": "revenue", "expression": "revenue"}], "disaggregated": true } }], "spec": { "version": 2, "widgetType": "counter", "encodings": { "value": {"fieldName": "revenue", "displayName": "Total Revenue"} }, "frame": {"showTitle": true, "title": "Total Revenue"} } }, "position": {"x": 0, "y": 0, "width": 2, "height": 3} }

Pattern 2: Aggregating widget (multi-row dataset, supports filters)

  • Dataset returns multiple rows (e.g., grouped by a filter dimension)

  • Use "disaggregated": false and aggregation expression

  • CRITICAL: Field name MUST match fieldName exactly (e.g., "sum(spend)" )

{ "widget": { "name": "total-spend", "queries": [{ "name": "main_query", "query": { "datasetName": "by_category", "fields": [{"name": "sum(spend)", "expression": "SUM(spend)"}], "disaggregated": false } }], "spec": { "version": 2, "widgetType": "counter", "encodings": { "value": {"fieldName": "sum(spend)", "displayName": "Total Spend"} }, "frame": {"showTitle": true, "title": "Total Spend"} } }, "position": {"x": 0, "y": 0, "width": 2, "height": 3} }

Table:

  • version : 2 (NOT 1 or 3!)

  • widgetType : "table"

  • Columns only need fieldName and displayName

  • no other properties!

  • Use "disaggregated": true for raw rows

{ "widget": { "name": "details-table", "queries": [{ "name": "main_query", "query": { "datasetName": "details_ds", "fields": [ {"name": "name", "expression": "name"}, {"name": "value", "expression": "value"} ], "disaggregated": true } }], "spec": { "version": 2, "widgetType": "table", "encodings": { "columns": [ {"fieldName": "name", "displayName": "Name"}, {"fieldName": "value", "displayName": "Value"} ] }, "frame": {"showTitle": true, "title": "Details"} } }, "position": {"x": 0, "y": 0, "width": 6, "height": 6} }

Line / Bar Charts:

  • version : 3

  • widgetType : "line" or "bar"

  • Use x , y , optional color encodings

  • scale.type : "temporal" (dates), "quantitative" (numbers), "categorical" (strings)

  • Use "disaggregated": true with pre-aggregated dataset data

Multiple Lines - Two Approaches:

  • Multi-Y Fields (different metrics on same chart):

"y": { "scale": {"type": "quantitative"}, "fields": [ {"fieldName": "sum(orders)", "displayName": "Orders"}, {"fieldName": "sum(returns)", "displayName": "Returns"} ] }

  • Color Grouping (same metric split by dimension):

"y": {"fieldName": "sum(revenue)", "scale": {"type": "quantitative"}}, "color": {"fieldName": "region", "scale": {"type": "categorical"}, "displayName": "Region"}

Bar Chart Modes:

  • Stacked (default): No mark field - bars stack on top of each other

  • Grouped: Add "mark": {"layout": "group"}

  • bars side-by-side for comparison

Pie Chart:

  • version : 3

  • widgetType : "pie"

  • angle : quantitative aggregate

  • color : categorical dimension

  • Limit to 3-8 categories for readability

  1. FILTERS (Global vs Page-Level)

CRITICAL: Filter widgets use DIFFERENT widget types than charts!

  • Valid types: filter-multi-select , filter-single-select , filter-date-range-picker

  • DO NOT use widgetType: "filter"

  • this does not exist and will cause errors

  • Filters use spec.version: 2

  • ALWAYS include frame with showTitle: true for filter widgets

Filter widget types:

  • filter-date-range-picker : for DATE/TIMESTAMP fields

  • filter-single-select : categorical with single selection

  • filter-multi-select : categorical with multiple selections

Global Filters vs Page-Level Filters

Type Placement Scope Use Case

Global Filter Dedicated page with "pageType": "PAGE_TYPE_GLOBAL_FILTERS"

Affects ALL pages that have datasets with the filter field Cross-dashboard filtering (e.g., date range, campaign)

Page-Level Filter Regular page with "pageType": "PAGE_TYPE_CANVAS"

Affects ONLY widgets on that same page Page-specific filtering (e.g., platform filter on breakdown page only)

Key Insight: A filter only affects datasets that contain the filter field. To have a filter affect only specific pages:

  • Include the filter dimension in datasets for pages that should be filtered

  • Exclude the filter dimension from datasets for pages that should NOT be filtered

Filter Widget Structure

CRITICAL: Do NOT use associative_filter_predicate_group

  • it causes SQL errors! Use a simple field expression instead.

{ "widget": { "name": "filter_region", "queries": [{ "name": "ds_data_region", "query": { "datasetName": "ds_data", "fields": [ {"name": "region", "expression": "region"} ], "disaggregated": false } }], "spec": { "version": 2, "widgetType": "filter-multi-select", "encodings": { "fields": [{ "fieldName": "region", "displayName": "Region", "queryName": "ds_data_region" }] }, "frame": {"showTitle": true, "title": "Region"} } }, "position": {"x": 0, "y": 0, "width": 2, "height": 2} }

Global Filter Example

Place on a dedicated filter page:

{ "name": "filters", "displayName": "Filters", "pageType": "PAGE_TYPE_GLOBAL_FILTERS", "layout": [ { "widget": { "name": "filter_campaign", "queries": [{ "name": "ds_campaign", "query": { "datasetName": "overview", "fields": [{"name": "campaign_name", "expression": "campaign_name"}], "disaggregated": false } }], "spec": { "version": 2, "widgetType": "filter-multi-select", "encodings": { "fields": [{ "fieldName": "campaign_name", "displayName": "Campaign", "queryName": "ds_campaign" }] }, "frame": {"showTitle": true, "title": "Campaign"} } }, "position": {"x": 0, "y": 0, "width": 2, "height": 2} } ] }

Page-Level Filter Example

Place directly on a canvas page (affects only that page):

{ "name": "platform_breakdown", "displayName": "Platform Breakdown", "pageType": "PAGE_TYPE_CANVAS", "layout": [ { "widget": { "name": "page-title", "multilineTextboxSpec": {"lines": ["## Platform Breakdown"]} }, "position": {"x": 0, "y": 0, "width": 4, "height": 1} }, { "widget": { "name": "filter_platform", "queries": [{ "name": "ds_platform", "query": { "datasetName": "platform_data", "fields": [{"name": "platform", "expression": "platform"}], "disaggregated": false } }], "spec": { "version": 2, "widgetType": "filter-multi-select", "encodings": { "fields": [{ "fieldName": "platform", "displayName": "Platform", "queryName": "ds_platform" }] }, "frame": {"showTitle": true, "title": "Platform"} } }, "position": {"x": 4, "y": 0, "width": 2, "height": 2} } // ... other widgets on this page ] }

Filter Layout Guidelines:

  • Global filters: Position on dedicated filter page, stack vertically at x=0

  • Page-level filters: Position in header area of page (e.g., top-right corner)

  • Typical sizing: width: 2, height: 2

  1. QUALITY CHECKLIST

Before deploying, verify:

  • All widget names use only alphanumeric + hyphens + underscores

  • All rows sum to width=6 with no gaps

  • KPIs use height 3-4, charts use height 5-6

  • Chart dimensions have ≤8 distinct values

  • All widget fieldNames match dataset columns exactly

  • Field name in query.fields matches fieldName in encodings exactly (e.g., both "sum(spend)" )

  • Counter datasets: use disaggregated: true for 1-row datasets, disaggregated: false with aggregation for multi-row

  • Percent values are 0-1 (not 0-100)

  • SQL uses Spark syntax (date_sub, not INTERVAL)

  • All SQL queries tested via execute_sql and return expected data

Complete Example

import json

Step 1: Check table schema

table_info = get_table_details(catalog="samples", schema="nyctaxi")

Step 2: Test queries

execute_sql("SELECT COUNT() as trips, AVG(fare_amount) as avg_fare, AVG(trip_distance) as avg_distance FROM samples.nyctaxi.trips") execute_sql(""" SELECT pickup_zip, COUNT() as trip_count FROM samples.nyctaxi.trips GROUP BY pickup_zip ORDER BY trip_count DESC LIMIT 10 """)

Step 3: Build dashboard JSON

dashboard = { "datasets": [ { "name": "summary", "displayName": "Summary Stats", "queryLines": [ "SELECT COUNT() as trips, AVG(fare_amount) as avg_fare, ", "AVG(trip_distance) as avg_distance ", "FROM samples.nyctaxi.trips " ] }, { "name": "by_zip", "displayName": "Trips by ZIP", "queryLines": [ "SELECT pickup_zip, COUNT() as trip_count ", "FROM samples.nyctaxi.trips ", "GROUP BY pickup_zip ", "ORDER BY trip_count DESC ", "LIMIT 10 " ] } ], "pages": [{ "name": "overview", "displayName": "NYC Taxi Overview", "pageType": "PAGE_TYPE_CANVAS", "layout": [ # Text header - NO spec block! Use SEPARATE widgets for title and subtitle! { "widget": { "name": "title", "multilineTextboxSpec": { "lines": ["## NYC Taxi Dashboard"] } }, "position": {"x": 0, "y": 0, "width": 6, "height": 1} }, { "widget": { "name": "subtitle", "multilineTextboxSpec": { "lines": ["Trip statistics and analysis"] } }, "position": {"x": 0, "y": 1, "width": 6, "height": 1} }, # Counter - version 2, width 2! { "widget": { "name": "total-trips", "queries": [{ "name": "main_query", "query": { "datasetName": "summary", "fields": [{"name": "trips", "expression": "trips"}], "disaggregated": True } }], "spec": { "version": 2, "widgetType": "counter", "encodings": { "value": {"fieldName": "trips", "displayName": "Total Trips"} }, "frame": {"title": "Total Trips", "showTitle": True} } }, "position": {"x": 0, "y": 2, "width": 2, "height": 3} }, { "widget": { "name": "avg-fare", "queries": [{ "name": "main_query", "query": { "datasetName": "summary", "fields": [{"name": "avg_fare", "expression": "avg_fare"}], "disaggregated": True } }], "spec": { "version": 2, "widgetType": "counter", "encodings": { "value": {"fieldName": "avg_fare", "displayName": "Avg Fare"} }, "frame": {"title": "Average Fare", "showTitle": True} } }, "position": {"x": 2, "y": 2, "width": 2, "height": 3} }, { "widget": { "name": "total-distance", "queries": [{ "name": "main_query", "query": { "datasetName": "summary", "fields": [{"name": "avg_distance", "expression": "avg_distance"}], "disaggregated": True } }], "spec": { "version": 2, "widgetType": "counter", "encodings": { "value": {"fieldName": "avg_distance", "displayName": "Avg Distance"} }, "frame": {"title": "Average Distance", "showTitle": True} } }, "position": {"x": 4, "y": 2, "width": 2, "height": 3} }, # Bar chart - version 3 { "widget": { "name": "trips-by-zip", "queries": [{ "name": "main_query", "query": { "datasetName": "by_zip", "fields": [ {"name": "pickup_zip", "expression": "pickup_zip"}, {"name": "trip_count", "expression": "trip_count"} ], "disaggregated": True } }], "spec": { "version": 3, "widgetType": "bar", "encodings": { "x": {"fieldName": "pickup_zip", "scale": {"type": "categorical"}, "displayName": "ZIP"}, "y": {"fieldName": "trip_count", "scale": {"type": "quantitative"}, "displayName": "Trips"} }, "frame": {"title": "Trips by Pickup ZIP", "showTitle": True} } }, "position": {"x": 0, "y": 5, "width": 6, "height": 5} }, # Table - version 2, minimal column props! { "widget": { "name": "zip-table", "queries": [{ "name": "main_query", "query": { "datasetName": "by_zip", "fields": [ {"name": "pickup_zip", "expression": "pickup_zip"}, {"name": "trip_count", "expression": "trip_count"} ], "disaggregated": True } }], "spec": { "version": 2, "widgetType": "table", "encodings": { "columns": [ {"fieldName": "pickup_zip", "displayName": "ZIP Code"}, {"fieldName": "trip_count", "displayName": "Trip Count"} ] }, "frame": {"title": "Top ZIP Codes", "showTitle": True} } }, "position": {"x": 0, "y": 10, "width": 6, "height": 5} } ] }] }

Step 4: Deploy

result = create_or_update_dashboard( display_name="NYC Taxi Dashboard", parent_path="/Workspace/Users/me/dashboards", serialized_dashboard=json.dumps(dashboard), warehouse_id=get_best_warehouse(), ) print(result["url"])

Complete Example with Filters

import json

Dashboard with a global filter for region

dashboard_with_filters = { "datasets": [ { "name": "sales", "displayName": "Sales Data", "queryLines": [ "SELECT region, SUM(revenue) as total_revenue ", "FROM catalog.schema.sales ", "GROUP BY region" ] } ], "pages": [ { "name": "overview", "displayName": "Sales Overview", "pageType": "PAGE_TYPE_CANVAS", "layout": [ { "widget": { "name": "total-revenue", "queries": [{ "name": "main_query", "query": { "datasetName": "sales", "fields": [{"name": "total_revenue", "expression": "total_revenue"}], "disaggregated": True } }], "spec": { "version": 2, # Version 2 for counters! "widgetType": "counter", "encodings": { "value": {"fieldName": "total_revenue", "displayName": "Total Revenue"} }, "frame": {"title": "Total Revenue", "showTitle": True} } }, "position": {"x": 0, "y": 0, "width": 6, "height": 3} } ] }, { "name": "filters", "displayName": "Filters", "pageType": "PAGE_TYPE_GLOBAL_FILTERS", # Required for global filter page! "layout": [ { "widget": { "name": "filter_region", "queries": [{ "name": "ds_sales_region", "query": { "datasetName": "sales", "fields": [ {"name": "region", "expression": "region"} # DO NOT use associative_filter_predicate_group - causes SQL errors! ], "disaggregated": False # False for filters! } }], "spec": { "version": 2, # Version 2 for filters! "widgetType": "filter-multi-select", # NOT "filter"! "encodings": { "fields": [{ "fieldName": "region", "displayName": "Region", "queryName": "ds_sales_region" # Must match query name! }] }, "frame": {"showTitle": True, "title": "Region"} # Always show title! } }, "position": {"x": 0, "y": 0, "width": 2, "height": 2} } ] } ] }

Deploy with filters

result = create_or_update_dashboard( display_name="Sales Dashboard with Filters", parent_path="/Workspace/Users/me/dashboards", serialized_dashboard=json.dumps(dashboard_with_filters), warehouse_id=get_best_warehouse(), ) print(result["url"])

Troubleshooting

Widget shows "no selected fields to visualize"

This is a field name mismatch error. The name in query.fields must exactly match the fieldName in encodings .

Fix: Ensure names match exactly:

// WRONG - names don't match "fields": [{"name": "spend", "expression": "SUM(spend)"}] "encodings": {"value": {"fieldName": "sum(spend)", ...}} // ERROR!

// CORRECT - names match "fields": [{"name": "sum(spend)", "expression": "SUM(spend)"}] "encodings": {"value": {"fieldName": "sum(spend)", ...}} // OK!

Widget shows "Invalid widget definition"

Check version numbers:

  • Counters: version: 2

  • Tables: version: 2

  • Filters: version: 2

  • Bar/Line/Pie charts: version: 3

Text widget errors:

  • Text widgets must NOT have a spec block

  • Use multilineTextboxSpec directly on the widget object

  • Do NOT use widgetType: "text"

  • this is invalid

Table widget errors:

  • Use version: 2 (NOT 1 or 3)

  • Column objects only need fieldName and displayName

  • Do NOT add type , numberFormat , or other column properties

Counter widget errors:

  • Use version: 2 (NOT 3)

  • Ensure dataset returns exactly 1 row

Dashboard shows empty widgets

  • Run the dataset SQL query directly to check data exists

  • Verify column aliases match widget field expressions

  • Check disaggregated flag (should be true for pre-aggregated data)

Layout has gaps

  • Ensure each row sums to width=6

  • Check that y positions don't skip values

Filter shows "Invalid widget definition"

  • Check widgetType is one of: filter-multi-select , filter-single-select , filter-date-range-picker

  • DO NOT use widgetType: "filter"

  • this is invalid

  • Verify spec.version is 2

  • Ensure queryName in encodings matches the query name

  • Confirm disaggregated: false in filter queries

  • Ensure frame with showTitle: true is included

Filter not affecting expected pages

  • Global filters (on PAGE_TYPE_GLOBAL_FILTERS page) affect all datasets containing the filter field

  • Page-level filters (on PAGE_TYPE_CANVAS page) only affect widgets on that same page

  • A filter only works on datasets that include the filter dimension column

Filter shows "UNRESOLVED_COLUMN" error for associative_filter_predicate_group

  • DO NOT use COUNT_IF(
    associative_filter_predicate_group) in filter queries

  • This internal expression causes SQL errors when the dashboard executes queries

  • Use a simple field expression instead: {"name": "field", "expression": "
    field"}

Text widget shows title and description on same line

  • Multiple items in the lines array are concatenated, not displayed on separate lines

  • Use separate text widgets for title and subtitle at different y positions

  • Example: title at y=0 with height=1, subtitle at y=1 with height=1

Related Skills

  • databricks-unity-catalog - for querying the underlying data and system tables

  • databricks-spark-declarative-pipelines - for building the data pipelines that feed dashboards

  • databricks-jobs - for scheduling dashboard data refreshes

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

databricks-python-sdk

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-dev

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

skill-test

No summary provided by upstream source.

Repository SourceNeeds Review