<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Databricks Workflow Task Failure - Custom Error Messages in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/172295#M56623</link>
    <description>&lt;DIV&gt;
&lt;P&gt;This is mostly how notebook tasks surface errors, not something you can fully control from your code. In a notebook task, &lt;CODE&gt;sys.exit()&lt;/CODE&gt; raises &lt;CODE&gt;SystemExit&lt;/CODE&gt;, which IPython intercepts. That's where the "An exception has occurred, use %tb…" line and the &lt;CODE&gt;To exit: use 'exit', 'quit'…&lt;/CODE&gt; warning come from. I'd use &lt;CODE&gt;raise&lt;/CODE&gt; over &lt;CODE&gt;sys.exit&lt;/CODE&gt;, and if you want cleaner output, move the check out of a notebook task.&lt;/P&gt;
&lt;H2&gt;Raise vs. sys.exit&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Raise an exception.&lt;/STRONG&gt; This is the right way to fail a notebook task. The task fails and the message shows in the run output. A traceback comes with it, but it's the normal, expected output.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Avoid &lt;CODE&gt;sys.exit()&lt;/CODE&gt; in notebooks.&lt;/STRONG&gt; It still fails the task, but you get the IPython wrapper text and the warning shown in your screenshot, so it's strictly noisier.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Don't use &lt;CODE&gt;dbutils.notebook.exit()&lt;/CODE&gt; to signal failure.&lt;/STRONG&gt; It ends the run &lt;EM&gt;successfully&lt;/EM&gt;, so downstream tasks will still run.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Getting the output down&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;1. Raise a short, purpose-built exception with the message you want users to read:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="language-python"&gt;class ContentGateError(Exception):
    pass

if not passed:
    raise ContentGateError("run_content_gate failed: 1,234 rows missing required content_id")
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The last line of the error will be &lt;CODE&gt;ContentGateError: run_content_gate failed: …&lt;/CODE&gt;, which is easy to spot. If you want the failure details to be the first thing people see, print a clear summary just before raising.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2. Keep the traceback short.&lt;/STRONG&gt; Raise the error at the top level of the notebook cell rather than from deep inside helper functions, since each frame adds to the traceback. If you wrap logic in functions, return a pass/fail result and raise in one place at the end. Setting &lt;CODE&gt;sys.tracebacklimit = 0&lt;/CODE&gt; may trim the stack further, but that's an interpreter setting and IPython doesn't always honor it, so test it on your runtime before you rely on it.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3. Use a different task type if you want truly minimal output.&lt;/STRONG&gt; The notebook UI adds the wrapper, so if the gate is just a check, there are two cleaner options [1]:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Python script task.&lt;/STRONG&gt; There's no IPython layer, so an uncaught exception or a non-zero exit gives plain Python-style output without the notebook warnings.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;SQL task or SQL-based check.&lt;/STRONG&gt; If the gate can be expressed in SQL, &lt;CODE&gt;raise_error&lt;/CODE&gt; or &lt;CODE&gt;assert_true&lt;/CODE&gt; fails with just your message, in the form &lt;CODE&gt;[USER_RAISED_EXCEPTION] &amp;lt;your message&amp;gt; SQLSTATE: P0001&lt;/CODE&gt; [2]:&lt;/LI&gt;
&lt;/UL&gt;
&lt;PRE&gt;&lt;CODE class="language-sql"&gt;SELECT assert_true(
  (SELECT count(*) FROM main.my_schema.my_table WHERE content_id IS NULL) = 0,
  'run_content_gate failed: rows with NULL content_id found'
);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;4. Consider a Condition (if/else) task for expected outcomes.&lt;/STRONG&gt; If these failures are expected validation results rather than errors, compute the result in one task and branch on it. That lets you route to a notification or cleanup task instead of failing a run with a stack trace [1].&lt;/P&gt;
&lt;H2&gt;Recommendation&lt;/H2&gt;
&lt;P&gt;If you need to stay in a notebook, raise a small custom exception with a one-line message from the top level of a cell. If you want output that's actually minimal, make the gate a Python script task, or a SQL task with &lt;CODE&gt;raise_error&lt;/CODE&gt;/&lt;CODE&gt;assert_true&lt;/CODE&gt;.&lt;/P&gt;
&lt;H2&gt;References&lt;/H2&gt;
&lt;P&gt;[1] Lakeflow Jobs | Databricks on AWS — &lt;A href="https://docs.databricks.com/aws/en/jobs" target="_blank"&gt;https://docs.databricks.com/aws/en/jobs&lt;/A&gt;&lt;BR /&gt;[2] Error handling in Databricks | Databricks on AWS — &lt;A href="https://docs.databricks.com/aws/en/error-messages" target="_blank"&gt;https://docs.databricks.com/aws/en/error-messages&lt;/A&gt;&lt;/P&gt;
&lt;/DIV&gt;</description>
    <pubDate>Thu, 08 Oct 2026 13:23:01 GMT</pubDate>
    <dc:creator>anuj_lathi</dc:creator>
    <dc:date>2026-10-08T13:23:01Z</dc:date>
    <item>
      <title>Databricks Workflow Task Failure - Custom Error Messages</title>
      <link>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/169842#M56177</link>
      <description>&lt;P&gt;Hi there, kind of silly question but I'm hoping there's a simple way to address this.&lt;/P&gt;&lt;P&gt;I'm trying to make sure that when certain job failure conditions arise, that a workflow task step fails. I've tried this with both raise RuntimeError and sys.exit, but in both cases I'm seeing more in the output than I would like.&lt;/P&gt;&lt;P&gt;I would like to output the most minimal amount of text so that users who are troubleshooting can easily read the custom error message we are outputing.&lt;/P&gt;&lt;P&gt;Is there another/better approach to what I'm trying to do, or is this a Databricks limitation in how raised errors or system exit messages are output?&lt;/P&gt;&lt;P&gt;Also, would one be recommended over the other (raised exception vs system exit)?&lt;/P&gt;&lt;P&gt;Below are examples for both:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ChristianRRL_0-1790348230722.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31504i1C9A956EDB45F7AC/image-size/medium?v=v2&amp;amp;px=400" role="button" title="ChristianRRL_0-1790348230722.png" alt="ChristianRRL_0-1790348230722.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ChristianRRL_0-1790348341444.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31505i7D08D23D25B229A1/image-size/medium?v=v2&amp;amp;px=400" role="button" title="ChristianRRL_0-1790348341444.png" alt="ChristianRRL_0-1790348341444.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 25 Sep 2026 15:03:44 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/169842#M56177</guid>
      <dc:creator>ChristianRRL</dc:creator>
      <dc:date>2026-09-25T15:03:44Z</dc:date>
    </item>
    <item>
      <title>Re: Databricks Workflow Task Failure - Custom Error Messages</title>
      <link>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/169890#M56186</link>
      <description>&lt;P&gt;Hey&amp;nbsp;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/96188"&gt;@ChristianRRL&lt;/a&gt;&amp;nbsp;!&lt;/P&gt;
&lt;P class="PlaygroundEditorTheme__paragraph"&gt;&lt;SPAN&gt;When a Python wheel/notebook/script task fails, Jobs always does three things:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL class="PlaygroundEditorTheme__ol1"&gt;
&lt;LI class="PlaygroundEditorTheme__listItem" value="1"&gt;&lt;SPAN&gt;Render the Python traceback&amp;nbsp;in task output (IPython / Databricks REPL&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;STRONG class="PlaygroundEditorTheme__textBold"&gt;showtraceback&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;SPAN&gt;).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="PlaygroundEditorTheme__listItem" value="2"&gt;&lt;SPAN&gt;Extract a one-line summary&amp;nbsp;(&lt;/SPAN&gt;&lt;STRONG&gt;&lt;STRONG class="PlaygroundEditorTheme__textBold"&gt;RuntimeError: &amp;lt;your message&amp;gt;&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;SPAN&gt;), which is the yellow line at the bottom of your screenshot.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="PlaygroundEditorTheme__listItem" value="3"&gt;&lt;SPAN&gt;Set the task termination message&amp;nbsp;to &lt;/SPAN&gt;&lt;STRONG&gt;&lt;STRONG class="PlaygroundEditorTheme__textBold"&gt;Workload failed, see run output for details.&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;SPAN&gt; That string is a fixed platform copy for “user code failed.” You cannot replace it with your custom message.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="PlaygroundEditorTheme__paragraph"&gt;&lt;SPAN&gt;Python wheel tasks are executed as notebook commands, so they receive the same wrapping. Jobs already strips some internal wheel frames, but your&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;STRONG class="PlaygroundEditorTheme__textBold"&gt;main()&amp;nbsp;/&amp;nbsp;raise&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;frames stay.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="PlaygroundEditorTheme__paragraph"&gt;&lt;SPAN&gt;There is&amp;nbsp;no supported API&amp;nbsp;today to fail a task with&amp;nbsp;&lt;/SPAN&gt;&lt;I&gt;&lt;EM class="PlaygroundEditorTheme__textItalic"&gt;only&lt;/EM&gt;&lt;/I&gt;&lt;SPAN&gt;&amp;nbsp;a custom string and no traceback &lt;/SPAN&gt;&lt;STRONG&gt;&lt;STRONG class="PlaygroundEditorTheme__textBold"&gt;(dbutils.notebook.exit(...)).&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;Also, it does&amp;nbsp;not&amp;nbsp;fail the task; it succeeds and returns a value.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="PlaygroundEditorTheme__paragraph"&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 26 Sep 2026 06:47:08 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/169890#M56186</guid>
      <dc:creator>K_Anudeep</dc:creator>
      <dc:date>2026-09-26T06:47:08Z</dc:date>
    </item>
    <item>
      <title>Re: Databricks Workflow Task Failure - Custom Error Messages</title>
      <link>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/172295#M56623</link>
      <description>&lt;DIV&gt;
&lt;P&gt;This is mostly how notebook tasks surface errors, not something you can fully control from your code. In a notebook task, &lt;CODE&gt;sys.exit()&lt;/CODE&gt; raises &lt;CODE&gt;SystemExit&lt;/CODE&gt;, which IPython intercepts. That's where the "An exception has occurred, use %tb…" line and the &lt;CODE&gt;To exit: use 'exit', 'quit'…&lt;/CODE&gt; warning come from. I'd use &lt;CODE&gt;raise&lt;/CODE&gt; over &lt;CODE&gt;sys.exit&lt;/CODE&gt;, and if you want cleaner output, move the check out of a notebook task.&lt;/P&gt;
&lt;H2&gt;Raise vs. sys.exit&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Raise an exception.&lt;/STRONG&gt; This is the right way to fail a notebook task. The task fails and the message shows in the run output. A traceback comes with it, but it's the normal, expected output.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Avoid &lt;CODE&gt;sys.exit()&lt;/CODE&gt; in notebooks.&lt;/STRONG&gt; It still fails the task, but you get the IPython wrapper text and the warning shown in your screenshot, so it's strictly noisier.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Don't use &lt;CODE&gt;dbutils.notebook.exit()&lt;/CODE&gt; to signal failure.&lt;/STRONG&gt; It ends the run &lt;EM&gt;successfully&lt;/EM&gt;, so downstream tasks will still run.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Getting the output down&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;1. Raise a short, purpose-built exception with the message you want users to read:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="language-python"&gt;class ContentGateError(Exception):
    pass

if not passed:
    raise ContentGateError("run_content_gate failed: 1,234 rows missing required content_id")
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The last line of the error will be &lt;CODE&gt;ContentGateError: run_content_gate failed: …&lt;/CODE&gt;, which is easy to spot. If you want the failure details to be the first thing people see, print a clear summary just before raising.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2. Keep the traceback short.&lt;/STRONG&gt; Raise the error at the top level of the notebook cell rather than from deep inside helper functions, since each frame adds to the traceback. If you wrap logic in functions, return a pass/fail result and raise in one place at the end. Setting &lt;CODE&gt;sys.tracebacklimit = 0&lt;/CODE&gt; may trim the stack further, but that's an interpreter setting and IPython doesn't always honor it, so test it on your runtime before you rely on it.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3. Use a different task type if you want truly minimal output.&lt;/STRONG&gt; The notebook UI adds the wrapper, so if the gate is just a check, there are two cleaner options [1]:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Python script task.&lt;/STRONG&gt; There's no IPython layer, so an uncaught exception or a non-zero exit gives plain Python-style output without the notebook warnings.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;SQL task or SQL-based check.&lt;/STRONG&gt; If the gate can be expressed in SQL, &lt;CODE&gt;raise_error&lt;/CODE&gt; or &lt;CODE&gt;assert_true&lt;/CODE&gt; fails with just your message, in the form &lt;CODE&gt;[USER_RAISED_EXCEPTION] &amp;lt;your message&amp;gt; SQLSTATE: P0001&lt;/CODE&gt; [2]:&lt;/LI&gt;
&lt;/UL&gt;
&lt;PRE&gt;&lt;CODE class="language-sql"&gt;SELECT assert_true(
  (SELECT count(*) FROM main.my_schema.my_table WHERE content_id IS NULL) = 0,
  'run_content_gate failed: rows with NULL content_id found'
);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;4. Consider a Condition (if/else) task for expected outcomes.&lt;/STRONG&gt; If these failures are expected validation results rather than errors, compute the result in one task and branch on it. That lets you route to a notification or cleanup task instead of failing a run with a stack trace [1].&lt;/P&gt;
&lt;H2&gt;Recommendation&lt;/H2&gt;
&lt;P&gt;If you need to stay in a notebook, raise a small custom exception with a one-line message from the top level of a cell. If you want output that's actually minimal, make the gate a Python script task, or a SQL task with &lt;CODE&gt;raise_error&lt;/CODE&gt;/&lt;CODE&gt;assert_true&lt;/CODE&gt;.&lt;/P&gt;
&lt;H2&gt;References&lt;/H2&gt;
&lt;P&gt;[1] Lakeflow Jobs | Databricks on AWS — &lt;A href="https://docs.databricks.com/aws/en/jobs" target="_blank"&gt;https://docs.databricks.com/aws/en/jobs&lt;/A&gt;&lt;BR /&gt;[2] Error handling in Databricks | Databricks on AWS — &lt;A href="https://docs.databricks.com/aws/en/error-messages" target="_blank"&gt;https://docs.databricks.com/aws/en/error-messages&lt;/A&gt;&lt;/P&gt;
&lt;/DIV&gt;</description>
      <pubDate>Thu, 08 Oct 2026 13:23:01 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/172295#M56623</guid>
      <dc:creator>anuj_lathi</dc:creator>
      <dc:date>2026-10-08T13:23:01Z</dc:date>
    </item>
    <item>
      <title>Re: Databricks Workflow Task Failure - Custom Error Messages</title>
      <link>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/172313#M56627</link>
      <description>&lt;P&gt;It's a platform limitation. Notebook tasks run through IPython, which always prints a traceback for an unhandled exception, so you can't fully suppress the extra output. sys.exit doesn't help either. In a notebook it raises SystemExit, which gets rendered as an error too, and it's less clear to read.&lt;/P&gt;&lt;P&gt;Recommendation: raise an exception, not sys.exit.&lt;/P&gt;&lt;P&gt;python&lt;BR /&gt;class DataQualityError(Exception):&lt;BR /&gt;pass&lt;/P&gt;&lt;P&gt;if bad_condition:&lt;BR /&gt;raise DataQualityError("Row count check failed: expected &amp;gt; 0, got 0")&lt;BR /&gt;The task is marked failed, and your message appears on the last line of the output, which is where people look first.&lt;BR /&gt;A specific exception name (not a generic RuntimeError) makes the cause obvious at a glance.&lt;BR /&gt;Keep the message to a single line, with the check name and the values.&lt;/P&gt;&lt;P&gt;To get truly minimal output, use a Python script task (or wheel) instead of a notebook. There, sys.exit("Row count check failed: expected &amp;gt; 0, got 0") prints only that message to stderr and fails the task with exit code 1, with no traceback.&lt;/P&gt;&lt;P&gt;Other things that help:&lt;/P&gt;&lt;P&gt;Don't use dbutils.notebook.exit() to signal failure. It ends the task as successful.&lt;BR /&gt;To surface the reason without opening the run, set a task value (dbutils.jobs.taskValues.set(...)) and reference it in a downstream notification or condition task.&lt;/P&gt;&lt;P&gt;If you paste your two examples, I'll tighten them.&lt;/P&gt;</description>
      <pubDate>Thu, 08 Oct 2026 16:36:39 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/databricks-workflow-task-failure-custom-error-messages/m-p/172313#M56627</guid>
      <dc:creator>aayush_410</dc:creator>
      <dc:date>2026-10-08T16:36:39Z</dc:date>
    </item>
  </channel>
</rss>

