Repository navigation
v0.9.7
Release v0.9.7
📦 NPM packages
🐳 Docker image
docker pull ms2data/malloy-publisher:0.9.7
docker pull ms2data/malloy-publisher:latest
ℹ️ Details
- Release branch:
release/v0.9.7 - Triggered by: @kylenesbit
Packages report .malloynb notebooks and #(filter) sources as warnings
A package's warnings (GET …/packages/{package}) now include one advisory entry per .malloynb notebook (model is its path) and one per source that declares deprecated #(filter) annotations (subject is the source name, reported once however many models import it). Both carry severity: "warn". Nothing else changes: such packages still load and run. Migrating is covered in Coming from #(filter).
A connection that cannot be used answers 502 or 424 with a reason, not 400 or 500
When a query could not run because of its connection, Publisher answered as if the query were wrong (400 Query execution failed: <driver text>) or as if Publisher had a bug (500 on schema listing). The driver text could also name an internal host, port or user.
Now a connection that cannot be used answers with a reason, on the query route, notebook cells, sqlQuery, sqlTemporaryTable, sqlSource, the table lookup, and schema and table listing. A 5xx means something is down and a retry can succeed; a 4xx means something is misconfigured and a retry fails the same way:
| Status | reason |
Meaning | Body |
|---|---|---|---|
| 502 | CONNECTION_FAILED |
the database connection is down: refused, reset, timed out, or closed by the server | fixed message |
| 424 | CONNECTION_AUTH_FAILED |
the database rejected the connection's credentials | fixed message |
| 424 | CONNECTION_NOT_FOUND |
the model names a connection the environment does not have, usually one deleted after the package was loaded | No connection named "<name>" found in config |
CONNECTION_FAILED is what marks a 502 as the customer's database being down rather than Publisher failing. The driver's text for the first two goes to the server log at warn. Publisher's MCP execute_query tells the agent the query is fine and not to rewrite it.
A query the database ran and rejected (a type mismatch, a division by zero, a permission on a table) is still a 400 with the database's text and no reason.
A connection route (sqlQuery, sqlSource and the others) given a connection name the environment does not have answers 404, as the listing routes already did. CONNECTION_NOT_FOUND is only for a model naming a connection that is gone.
If you branch on the old 400 or 500, branch on reason instead. sqlQuery, sqlTemporaryTable and sqlSource still answer 502 with no reason for a driver failure that is none of these.
How each is recognized, from the driver's own fields on the error and its cause:
- Unreachable: Node's socket codes (
ECONNREFUSED,ECONNRESET,ETIMEDOUTand others), a Postgres SQLSTATE in class08or57P01-57P03, or MySQL'sfatalflag, unless its code names a config fault: a wrong database name, an unsupported auth mode or plugin, or aHANDSHAKE_TLS failure. mysql2 marks all of thosefataltoo.ENOTFOUND, a host name that does not resolve, is left out: it is almost always a wrong host in the config, which a retry will not fix. Some failures arrive with no code and are matched from the start of the message: node-pg'sConnection terminated unexpectedly, and on MySQLCan't add new command when connection is in closed state,Connection lost: The server closed the connection.and a Node socket error such asread ECONNRESET, because Malloy's MySQL driver keeps only the text of a query error. - Credentials: a Postgres SQLSTATE in class
28, MySQLER_ACCESS_DENIED_ERROR, Snowflake login codes390100,390144,390195and390318, and theBigQueryAuthenticationErrorMalloy's BigQuery driver raises. - Missing connection: Publisher's connection lookup, when Malloy's lookup fails for a name the environment does not configure.
A failure that matches none of these keeps its old status. Not covered yet:
- Rejected Postgres credentials on the table lookup. Malloy's Postgres driver returns that failure as text without its SQLSTATE, so it answers a plain 502. A database that is down is still recognized there, from the socket error in the text.
- BigQuery on schema and table listing, the table lookup and
sqlSource. Its SDK reports rejected credentials as a plain 401 error, and Malloy's driver returns table-lookup failures as text. - Databricks, and the DuckDB family (DuckLake, MotherDuck), whose errors carry no code. A catalog that is down still answers 400 on the query route.
compile_model at package scope reports dashboard and render-tag findings before you save
A tile naming a view that does not exist, a # drill pointing at no dashboard, a suggest naming a missing query, a tile reading a source the package's surface does not export, and an unknown render tag all compile cleanly. Until now only a package load reported them, so compile_model returned success and the problem showed up after saving and reloading.
compile_model and POST …/compile at scope: "package" now run the render-tag and dashboard checks a reload runs, over the compiled result, what-if replacement included. Findings come back with code render-tag or dashboard-lint, no position, and the subject (the view, field or given) leading the message. Each keeps the severity a load gives it, so a finding the load reports as an error makes the compile status: "error". scope: "file" is unchanged and does not run these checks. publisher_notebook_discovery_total still counts served packages only.
- A what-if dashboard that does not compile is still a dashboard. It is judged by the replacement text you sent, so a
# drillto it is no longer reported as pointing at nothing. - A check that cannot run is reported, not fatal. A dashboard check that throws returns one
warnsaying the findings are unknown rather than clean, instead of failing the whole call. A model that will not hydrate costs only its own findings: it gets anerrorof its own, since the reload would fail on it, and every other file keeps its findings. - No repeated
#(authorize)log lines. A package-scope compile no longer logs each model's#(authorize)warnings again on every call; the package logged them when it loaded.
What's Changed
- skills: resolve a value the user typed to the stored string before filtering on it by @jswir in #1338
- chore(release): stamp 0.9.6 on main by @sagarswamirao in #1346
- skills: correct three stale materialization rules, and say how to confirm a table is read by @girishjeswani in #1340
- fix: seven agent-authoring rough edges in MCP tools, dashboards and skills by @jswir in #1272
- fix(server): answer a database connection that is down as 502 CONNECTION_FAILED, and a misconfigured one as 424 by @jswir in #1331
- ci(release): stamp release notes on the release branch, merge it back as the release PR, and check main is in sync with npm by @sagarswamirao in #1345
- docs(connections): document DuckDB setupSQL and its pitfalls by @housejester in #1348
- fix(deps): move handlebars to 4.7.10 to clear two new CRITICALs by @sagarswamirao in #1362
- skills: audit the materialization skill against main, correct five wrong rules, and split it into a core file plus five references by @housejester in #1364
- feat(server): report .malloynb notebooks and #(filter) sources as package warnings by @kylenesbit in #1370
Full Changelog: v0.9.6...v0.9.7