<p>Here is a small release about a large amount of wasted time.</p><p>A query fails. The server says something. You read it, you form a theory, you go looking. Sometimes the theory is right and the fix takes ten seconds. And sometimes — more often than any of us would admit — the theory is wrong, and you spend ten minutes hunting a typo that isn't there, because the actual cause was something the message told you and you didn't hear it.</p><p>Elyra SQL Client 0.10.1 adds <strong>Error help</strong>: when a query fails, the server's message is classified into a cause, and the matching next step is offered as a button. That's the whole feature. What's interesting is why it's shaped the way it is.</p><h2>The case that pays for it</h2><p>You've got four engines in this client now — Elyra SQL, MySQL, SQLite and, since 0.10.0, ClickHouse — and they don't all speak the same SQL. Run this on ClickHouse:</p><pre><code class="language-sql">SELECT customer_id, GROUP_CONCAT(product) FROM orders GROUP BY customer_id;
</code></pre><p>and the server says:</p><pre><code class="language-text">Code: 46. DB::Exception: Unknown function GROUP_CONCAT.
Maybe you meant: ['groupArray']. (UNKNOWN_FUNCTION)
</code></pre><p>The SQL is valid. It's valid MySQL, and you've written it a thousand times. Nothing in you thinks "wrong dialect"; everything in you thinks "I typed it wrong". So you check the spelling, the parentheses, the quotes. You paste it into another tab. It runs there. Now you're confused and you've lost ten minutes.</p><p>With <strong>Error help</strong> on, the same failure shows the server's message — always, unchanged — and beneath it:</p><blockquote><p><strong>This engine doesn't implement that.</strong> ClickHouse has no <code>GROUP_CONCAT</code>; the server suggests <code>groupArray</code>. The statement isn't wrong, it's written for a different dialect.</p><p>▸ <strong>Open the ClickHouse functions reference</strong></p></blockquote><p>The message said <code>Unknown function</code>. The classification's contribution is to hear it — to say, in one line, that this is a category-of-engine problem and not a category-of-you problem. That reframing is the entire ten minutes.</p><h2>The other buttons</h2><p>The classifier sorts a failure into a small set of causes, and each cause has a next step that's actually a button:</p><p>The server says… Cause The button <code>Unknown column 'custmer_id'</code> unknown column <strong>Show columns</strong> — the table's columns, right there, so you see <code>customer_id</code> <code>Access denied; you need the PROCESS privilege</code> missing privilege <strong>User administration</strong> — the grant screen for this connection <code>Query execution was interrupted, maximum statement execution time exceeded</code> ran too long <strong>Statement timeout</strong> — the connection's setting, not a generic preferences page <code>Lost connection to server during query</code> looks like timing <strong>Try again</strong> — because sometimes the honest answer is that <code>Unknown function GROUP_CONCAT</code> this engine doesn't implement that <strong>Functions reference</strong> for the engine you're actually on</p><p>None of these is clever. Each one is the thing you'd do next anyway, if you'd correctly heard the message. The button saves the hearing and the navigation, and — the part that matters — it puts the right next step in front of you rather than the one your theory would have picked.</p><h2>How it decides</h2><p>The classification is done by Jev, TypeSafe's judgment model. If you've read about the assistant in 0.9.0 you might expect this to be another chat model, and it deliberately isn't.</p><p>Jev is a classifier. You give it a state — here, the error message and the engine's name — and a typed question: which of these causes is this? It returns a category with a probability, not a paragraph. <code>unknown_column: 0.94</code>. That's what lets the answer become a button: a category maps to an action, a paragraph doesn't. It's also fast (about a second) and cheap (fractions of a cent), which is what you want for something that runs on every failure rather than on request.</p><p>And it's honest about confidence. If the top category isn't clearly ahead — the message is ambiguous, the engine's phrasing is one it hasn't seen — no hint appears. You get the server's message and nothing else, exactly as before. We'd rather show nothing than show a confident wrong button, because a wrong button is worse than no button: it's your wrong theory, now with institutional backing.</p><h2>What is sent</h2><p>This is a client that sits next to production databases, so the boundary comes before the feature.</p><p><strong>Sent:</strong> the server's error message, and the engine's name.</p><p><strong>Not sent:</strong> your statement. Your schema. Any row. Anything else.</p><p>The message already names whatever was missing — the column, the function, the privilege. That's why it's enough on its own, and it's also why we didn't need to send the query that produced it. If your statement had a customer's name in a <code>WHERE</code> clause, that name stays on your machine. If your error message quotes a column called <code>salary</code>, the classifier learns that a column is called <code>salary</code>, which is the same thing the assistant would learn from your schema and nothing more.</p><p>The key is yours — a TypeSafe key, stored in the OS keychain beside your database passwords, never in a file — and the feature is off until you add one. No key, no calls, no change from 0.10.0.</p><h2>What it cannot do</h2><p><strong>Error help gates nothing.</strong></p><p>This is the sentence we most want to land, because "AI in the error path" could reasonably make a database administrator nervous. So, precisely: the write rails, the production confirmation and the read-only refusal are all enforced in code, before any query runs, and they do not consult Jev. They can't — they have to work when the service is down, when your key expires, when TypeSafe has an outage at 3 a.m. A classification only ever adds a suggestion to a failure that has already happened. It never decides whether something runs, never rewrites your statement, never executes anything. The server's own message is always shown alongside, unedited, and if you turn <strong>Error help</strong> off tomorrow the client behaves exactly as it did yesterday.</p><p>An assistant that could act on its own judgment would be a different — and worse — feature. This one has the authority of a colleague leaning over your shoulder saying "that's a ClickHouse thing, not a typo." Useful, occasionally wrong, and never holding the keyboard.</p><h2>Turning it on</h2><p><code>⌘,</code> (<code>Ctrl+,</code> on Linux) → <strong>Error help</strong> → paste a TypeSafe key. That's it. The next query that fails will show you what it thinks, if it's sure enough to say.</p><p>The <a target="_blank" rel="noopener noreferrer nofollow" href="https://elyracode.com/docs/sql-client/sql-editor#when-a-query-fails">SQL editor guide</a> has the causes and buttons; the <a target="_blank" rel="noopener noreferrer nofollow" href="https://elyracode.com/docs/sql-client/security">security page</a> has the boundary in one paragraph, for whoever needs to sign off on it. Download at <a target="_blank" rel="noopener noreferrer nofollow" href="https://elyracode.com/sql/client">elyracode.com/sql/client</a> — macOS on Apple silicon, Linux on x86_64 and ARM64, signed and verified by the updater.</p><p>Run something with <code>GROUP_CONCAT</code> against ClickHouse. Read the message. Then read the line under it, and notice how much shorter the ten minutes got.</p>