com um clique
serdes-yaml-edit
// Edit Metabase serdes YAML files (cards, dashboards, databases) with correct portable references and structural conventions. Use when modifying exported YAML content.
// Edit Metabase serdes YAML files (cards, dashboards, databases) with correct portable references and structural conventions. Use when modifying exported YAML content.
Guide Clojure and ClojureScript development using REPL-driven workflow, coding conventions, and best practices. Use when writing, developing, or refactoring Clojure/ClojureScript code.
Export content from a running Metabase instance, validate with checkers, edit YAML, and import back. Use when the user wants to export, import, or run the full serdes round-trip workflow.
Drive Metabase's UI with the Playwright MCP browser tools (mcp__playwright__browser_*). Covers the snapshot/act/check pattern, Mantine component pitfalls (Menu race, Select/MultiSelect, the Escape-closes-modal trap, portal scoping), and Metabase-specific login flows. Use whenever a session needs to interact with the Metabase UI through Playwright MCP.
Review Cypress E2E spec files for Metabase conventions, common gotchas, and flakiness/performance issues. Use when reviewing pull requests or diffs containing Cypress spec files in e2e/test/scenarios/.
Run Cypress E2E tests, analyze failures including screenshots, and stress test for flakiness
Analyze React component source code to understand UI structure, then generate idiomatic Cypress E2E tests following Metabase conventions. Falls back to Playwright MCP browser exploration only when code reading and screenshot debugging are insufficient.
| name | serdes-yaml-edit |
| description | Edit Metabase serdes YAML files (cards, dashboards, databases) with correct portable references and structural conventions. Use when modifying exported YAML content. |
Run both checkers after every edit. No exceptions. Do not batch multiple edits before validating.
clojure -M:run:ee --mode checker --checker structural --export /path/to/export-dir
clojure -M:run:ee --mode checker --checker cards --export /path/to/export-dir
If either checker fails, fix the issue before making further edits.
Serdes YAML uses portable references instead of integer IDs. This is the most important concept for editing.
String name: "Sample Database"
Array of [database, schema, table]:
table_id:
- Sample Database
- PUBLIC
- ACCOUNTS
Array of [database, schema, table, field]:
id:
- Sample Database
- PUBLIC
- ACCOUNTS
- EMAIL
field_ref:
- field
- - Sample Database
- PUBLIC
- ACCOUNTS
- EMAIL
- null
The outer array is [field, <field-path>, <options>]. The options are usually null.
Entity ID string (21 characters): "Qk5TgsNx4ubXIUtsQmT8G"
dataset_query:
database: Sample Database
query:
source-table:
- Sample Database
- PUBLIC
- ACCOUNTS
type: query
These rarely break validation:
name - card/dashboard display namedescription - card/dashboard descriptiondisplay - visualization type (table, bar, line, pie, etc.)visualization_settings - chart configurationarchived - true/falsecollection_id - move to a different collection (use entity_id of target collection, or null for root)These must use valid portable refs and will be caught by the cards checker if wrong:
dataset_query - the query definitionresult_metadata - column metadata (must match the query's output columns)table_id - must reference a table that exists in the exportdatabase_id - must reference a database that exists in the exportEach entry in result_metadata describes an output column. When changing a query's source table or fields, you must update result_metadata to match. Each field entry needs at minimum:
name - column name (e.g., EMAIL)base_type - Metabase type (e.g., type/Text, type/Integer, type/DateTime)display_name - human-readable namefield_ref - portable field referenceid - portable field pathtable_id - portable table pathsource - usually fieldsChange name: at the top level. Safe, no ref changes needed.
Update all of these consistently:
table_id - top-leveldataset_query.query.source-table - in the queryresult_metadata - every field entry's id, field_ref, and table_iddataset_query:
database: Sample Database
query:
source-table:
- Sample Database
- PUBLIC
- ORDERS
filter:
- ">"
- - field
- - Sample Database
- PUBLIC
- ORDERS
- TOTAL
- null
- 100
type: query
display: bar # was: table
Valid types: table, bar, line, pie, scalar, row, area, combo, scatter, funnel, map, pivot, progress, gauge, waterfall
The export directory IS the reference catalog. When you need to find the correct name for a database, table, or field, look it up directly from the export.
ls databases/
Each entry is a database name (directory for serdes format, .yaml for concise format).
ls databases/<db-name>/schemas/<schema>/tables/
Example: ls databases/Sample\ Database/schemas/PUBLIC/tables/ shows ACCOUNTS, ORDERS, PRODUCTS, etc.
ls databases/<db-name>/schemas/<schema>/tables/<table>/fields/
Example: ls databases/Sample\ Database/schemas/PUBLIC/tables/PRODUCTS/fields/ shows CATEGORY.yaml, TITLE.yaml, PRICE.yaml, etc. The filename (minus .yaml) is the field name.
Card filenames encode the entity ID: <entity-id>_<slug>.yaml. The entity ID is the part before the first underscore (21 characters).
When a checker reports errors, follow this loop:
Do not guess at fixes. Always look up the correct value from the export.
The structural checker validates YAML shape against Malli schemas. Common errors:
Missing required key with typo suggestion:
Missing required key 'name' - found 'nameee' which may be a typo
Fix: rename the typo'd key back to the correct name. The checker tells you what it expected and what it found.
Wrong type:
'archived' should be a boolean, got: "yes"
Fix: use true/false, not strings.
Unknown key:
Unknown key 'foobar' in card
Fix: remove the key, or check if it's a typo of a known key.
The cards checker validates that queries resolve against exported metadata. Error types:
UNRESOLVED REFERENCES:
UNRESOLVED REFERENCES:
- field: Sample Database.PUBLIC.PRODUCTS.CATEGORYYY
The dotted path tells you exactly which reference failed. Look up the correct value:
databases/.../tables/<table>/fields/databases/.../schemas/<schema>/tables/databases/ERROR (query construction failed):
ERROR: Error creating query from legacy query: Invalid output: ...
Usually means the query structure is malformed. This often follows unresolved references - fix the refs first, then re-check.
ERROR (nil name):
ERROR: Invalid output: {:name ["should be a string, got: nil"]}
The card is missing its name field (likely a structural issue that also affects the cards checker).
Card files: collections/<collection-path>/cards/<entity-id>_<slug>.yaml
The filename slug should match the card name (lowercase, underscored). If you rename a card, consider renaming the file to match, though import works on entity_id not filename.
entity_id - this is the identity of the object, changing it creates a new object on importserdes/meta - internal serdes metadata, leave it alonecreated_at - timestamp, no reason to changecreator_id - email reference, leave itmetabase_version - informational, leave it