Skip to content

August 2026

  • An imported Alteryx workflow now arrives with its comments and containers. The notes an Alteryx author wrote around their work, and the containers they grouped tools into, used to be discarded — so a converted workflow lost every bit of the explanation that came with it. They now come across as canvas objects: a comment box becomes a note, a comment box drawn as an empty outline around a set of tools becomes a highlight box, and a Tool Container becomes a group holding the steps that were inside it, keeping its caption, whether it was folded shut, and whether it was switched off. Nested containers come across as nested groups. Move, edit, recolor, or delete any of them like one you drew yourself.

    As canvas objects rather than steps, they also stop costing anything at run time. Each one used to become a do-nothing step with a warehouse table of its own: across our 178-workflow Alteryx reference set that was 2,413 steps of the 4,759 imported, and 2,409 tables nothing ever wrote to.

    Two things behave differently from the original, both deliberately. A switched-off Tool Container’s tools are still not imported — Alteryx does not run them either — but the container now comes across as a highlight box carrying its caption, so you can see what was there. And box colors are not carried over: the canvas offers a fixed set of six, and Alteryx boxes are almost always white or grey, so every one would arrive the same shade; they come in with the canvas default instead. Workflows imported before this release keep what they were given — import again to bring their comments and containers over. See Migrate Alteryx Workflows.

  • Excel exports are around twice as fast, and no longer grow their memory use with the size of the export. A large export previously held the whole result in memory while it built the file, so the biggest exports were also the ones most likely to run out of room and fail. The file is now built as the data is read, so the memory needed stays flat whatever the row count, and a typical large export finishes in roughly half the time. The resulting workbook is unchanged.

  • An Excel export too large for a worksheet now stops immediately and says why. A worksheet holds at most 1,048,576 rows and 16,384 columns, and a step asking for more used to spend the whole export producing a file Excel then refused to open. It now checks before it starts and names CSV and Parquet as the alternatives. Very large exports that exceed what the file format allows are reported the same way. See Export to Excel.

  • AI agents connected over MCP get leaner results, and are told when a list was cut short. Listing and lookup tools now return the first 25 matches per page rather than 50, and an agent can name the columns it wants with fields=[...] instead of taking the whole record — so a routine “list the tables in this project” costs a fraction of the agent’s limited reading capacity, leaving more room for your actual question. A page that was capped now says so explicitly, so an agent asks for the next page instead of quietly treating the first 25 as the complete answer, and asking for a column that doesn’t exist returns a clear error naming the columns that do, rather than silently leaving it out. Nothing is out of reach: raise limit, or page with the cursor. See Getting Started with AI Coding Agents.

  • A large result now sends each field name once instead of once per row. Where every row of a result carries the same fields, it comes back column-oriented — the field names in one list, the values in another — which is around 30% fewer characters on typical listing traffic and leaves correspondingly more of an agent’s reading capacity for your question. Connected agents are told about the shape and read it without any prompting from you, and no value is changed on the way. Small results, and results whose rows differ, are unchanged. If you read these responses from your own code rather than through an agent, handle both shapes. See Column-Oriented Results.

  • The AI assistant carries a leaner tool catalog. The list of available tools the assistant loads on every turn is about a third smaller, with no loss of capability, so more of its capacity goes to your question. A batch of tool descriptions that told it the wrong thing — naming a tool that doesn’t exist, describing an optional field as required, quoting an error the platform never returns — has also been corrected, so it wastes fewer turns on requests that were never going to work.

  • Cost-tracing can search combinations of dimensions. Where your workspace has explanatory-cut discovery switched on, asking what drove a change in an allocated cost now also tests combinations — a move confined to one region and one product line, say — rather than one dimension at a time. Previously the combination search never ran at all unless it was requested explicitly, which nothing did. The answer stays conservative: where nothing explains the move on its own, it says so rather than picking something. Both searches remain off by default. See Tracing Allocations with an MCP-Connected AI Agent.

  • The step palette in the Visual Workflow Designer is now organized into folders. Every step type used to sit in one long list you scrolled through. Steps are now filed in ten folders that start closed, so you see a short, scannable list instead of the whole catalog — and your favorites stay pinned above the folders, where they were. Filter… still searches everything at once, open or closed, and returns a plain list of matches.

    Clicking a step now adds it. It appears near the top left of the canvas, already selected, ready for you to drag where you want it — and if you picked the wrong one, Delete removes it without hunting for it first. Dragging a step from the palette still drops it exactly where you let go.

    Step names are long, so you can widen the palette by dragging the divider beside it, and it remembers the width for next time. See Advanced Workflows.

  • Dashboards now hold their cached results for an hour instead of five minutes. Because republishing a table now clears its charts’ cached results immediately, the cache no longer has to expire quickly to keep a dashboard current — so the default lifetime has been raised, and you can set it higher still to match how often the data actually changes. Set it in seconds on a database, under Advanced → Performance → Chart cache timeout, or on a single dataset under Settings → Cache timeout. On a table that reloads overnight, an hour or a day means a morning’s dashboard views are served from cache instead of re-querying the warehouse each time — which is where most of a slow dashboard’s time goes.

    You do not need to change anything to get this — the new default applies everywhere. One case is worth checking: if a table is written to by something outside PlaidCloud, nothing tells its dashboards to drop their cache, so the lifetime is all that refreshes them. Those can now be up to an hour behind rather than five minutes, so set a shorter lifetime on those datasets. See Dashboard Caching.

  • Workflow runs are lighter on the platform. A running workflow now asks PlaidCloud for far less of the same information while it works, which frees up capacity in busy workspaces where many workflows run at once.

  • Creating a dashboard user account is now an administrator-only action. Inside the dashboard service, adding or editing a user account directly is now limited to administrators, and the screens for creating and editing pending registrations have been removed. Nothing changes about how people get to a dashboard: your dashboard account is set up for you the first time you open a dashboard from PlaidCloud, and what you can see there follows from your PlaidCloud workspace membership and security groups. Add, change, and remove people in PlaidCloud rather than inside the dashboard service — accounts made directly in the dashboard service are not connected to your workspace membership and are easy to leave behind. See Managing Workspace Members.

  • A workspace no longer becomes slow to respond because of requests whose contents never arrived. Where a request reached PlaidCloud announcing itself but its contents did not follow, the platform went on waiting for contents that were never coming — for as long as twenty minutes — even though your browser had given up on that request after twenty seconds. Each one held a slot on the process that serves the whole workspace, so enough of them accumulating made everything slow to respond, and only restarting the workspace cleared them. Such a request is now given up on after fifteen seconds. Nothing you do legitimately takes that long to send, and file uploads, which genuinely are large, are handled separately and are unaffected.

  • Asking an AI assistant to break an allocation change down by a field that is blank everywhere no longer reports the whole change as coming from a single member. Breaking a change down by a field gathers together the rows that share a value — and rows with no value gather together too, so a field left blank on every row produced one group holding the entire change. The assistant then described that as perfectly concentrated in one member, at full confidence, with nothing to suggest otherwise. It was found on a real model where the field was blank on all 2.4 million rows in the period being compared. The assistant now tells you the field is not filled in for those rows, withholds the concentration figures rather than reporting them as 100%, and suggests either a field that is populated or dropping the breakdown altogether so it can find the field that best explains the change itself. Where a second grouping field is populated, the breakdown is genuine and is kept exactly as it was, with the blank field simply noted. A blank value also now reads as (no value) or (blank) rather than the word None, and the two are kept apart because they are genuinely different. The headline change, its totals and how it was attributed were always correct and are unchanged — only the breakdown was wrong. See Tracing Allocations.

  • Asking what a change to one table would do downstream no longer answers with a figure it could not work out. Where the calculation for one step failed, the result that step writes was reported as receiving the whole change — a maximum, presented exactly like a measured answer, with nothing to tell the two apart. Everything below that step was then estimated from it, so a whole branch of the answer read as ordinary measured estimates. That result now carries no figure at all, the answer says which steps could not be measured and why, and the totals cover only the results that were measured. Nothing downstream of an unmeasured step is estimated from it, and the answer tells you those results are missing rather than leaving you to notice. A result measured from only part of what writes it now says so too, and names the step that could not be read — the figure is a real measurement of what could be read, so it stands, but it is not the whole result and should not be read as a floor. A failure that could previously end the whole request with an error is now reported this way instead. See Tracing Allocations.

  • A workflow step saved with an output column that has no data type now runs. Adding an output column by hand used to leave it without a type. A new row now starts as Text so the step saves (below), but a step already saved that way still failed when it ran — it could not build its output table. The type is now worked out as the step starts, from the source column that output column reads. Where there is nothing to read it from the column is treated as text: an Extract SQL step’s columns come from the query you wrote rather than from a mapped source, and where several sources carry that column name under types that disagree, text is used rather than guessing one of them, since a wrong guess produces a conversion the warehouse can reject. This reaches every step that builds its output table from configured columns — Table Lookup, all four Joins, both Unions, the Extracts, Append, Upsert, the two geospatial steps and the file imports. Multi-Table Join is the deliberate exception: it stops and names the column instead, which is more useful than a guess in a step joining several tables. Setting the column’s Type in the step form remains how you say what the column should actually be; it is no longer the only way to make the step run. See Column Data Type.

  • Creating a table with a column left without a data type no longer fails outright. The column is created as text. This covers tables built through the API and through the AI assistant, where a column can be sent with no type at all rather than with a type you chose. It is a separate fix from the step behaviour above and does not depend on it.

  • A Macro Concurrent step no longer waits forever on a child invocation that has stopped responding. A child reports its own result when it finishes, so a child whose machine stopped without warning never reported anything — and the step went on waiting for it. There was no error and no progress to see: one run sat at Completed 0 of 29 loops for eighteen minutes, with nothing to do but stop it by hand. The step now checks that each child it is waiting on is still alive, and gives up on one that is not — stopping it, cleaning up after it, and failing at the end naming that invocation, the last state it reported, and when it last reported it. The other children are unaffected: they finish and their output tables are written as normal, so one unresponsive invocation out of twenty-nine no longer discards the other twenty-eight. A child working through a single long-running step is left alone for as long as it takes, and a check that cannot be answered — while the platform is briefly unreachable, for instance — is not treated as an answer. See When a Child Invocation Stops Responding.

  • An ML: Train Model step can now save a large model. A random forest left at its default hundred trees could not be saved at all: training itself succeeded, and the step then spent close to four minutes writing the model away before the connection to the warehouse dropped, reporting Broken pipe or Lost connection — which says nothing about what went wrong and does not tell you the training had worked. A decision tree over the same data saved without trouble, so what mattered was the size of the model, not the algorithm you chose. Models are now compressed before they are stored, and a model too large for a single value is split across as many rows as it needs, so the sizes that used to fail now save normally. A model still too large — more than 128 MB compressed, around twice what a default hundred-tree forest produces — now stops as soon as training finishes and tells you its size and the limit, instead of running for minutes and failing with a connection error.

    Two things to know if you read a model table directly rather than passing it to an ML: Score step. It may now hold more than one row, so read metrics_json from a single row — WHERE chunk_index = 0 — rather than assuming there is only one. And the stored model is compressed, so reassembling it yourself means joining the pieces in chunk_index order and decompressing before you unpickle. ML: Score handles all of this, and stops with an error if any piece of the model is missing rather than scoring with an incomplete one. Models trained before this release are still read as they were. See How the Model Is Stored.

  • A report text block now prints the value of a column its text names, instead of printing the reference itself. Text that referred to a column — the attribution line under a converted Alteryx map, for example — was written into the report with the reference still in it, so the finished PDF read [Year:A] © Mapbox where it should have read 2026 © Mapbox. The step reported success and the document looked normal, so there was nothing to notice until someone read the page. Naming a column that the text cannot read now stops the step and says which column, rather than printing the reference onto the page. Ordinary bracketed prose is untouched: a time like [12:30] and an aside like [Note: continued] still print as written. Re-run a report to correct it. See Report Text.

  • A shaded map’s legend now prints the band names the map defines. A converted Alteryx Report Map carries its own band names — High, Above Average, Average, Below Average, Low on a typical map — and the legend ignored them, labelling each band with the range of values it covered instead, down to a band shown as 22322 - 22322. The names are now used. Where they cannot be matched to the bands actually drawn — the shaded values do not reach every band, only some bands are named, or more than one layer is shaded — the step stops and says so, rather than printing a legend that reads correctly while naming the wrong bands. A map that names no bands still labels them by range, so existing maps are unchanged. See Report Map.

  • A date column in an Excel export shows as a date again, rather than as a number like 44355. Date columns were written without their date formatting, so Excel displayed the underlying number instead. Columns holding both a date and a time were not affected. Re-run the export to correct an existing file.

  • Re-importing an Alteryx workflow no longer overwrites the first import’s results. Every import names its tables after the workflow, so two imports of the same workflow — what happens whenever a first import needs correcting — asked for the same names. The second import created its own tables and then went on using the first import’s, so the two shared one set: each run replaced the other’s output, and a run that failed partway left the earlier import’s finished results empty. Both runs reported success. An import that asks for a name the project already holds now uses the table it actually created, named with a -duplicate- suffix, so each import keeps its own data. The same applies to two workflow files whose names match, and to importing into a project that already holds a table of that name. Imports you already ran are not repaired — re-import those workflows to separate them. See Migrate Alteryx Workflows.

  • Converted Alteryx workflows no longer write over each other’s tables. Each converted step writes a table named after the Alteryx tool it came from — tool_4_out for Tool 4 — and Alteryx numbers tools per file, so those names repeat across workflows. A PlaidCloud project is a single table namespace, so importing a folder of Alteryx workflows into one project, which is the usual way to migrate, had each import claiming names an earlier one was already using. Across a 178-workflow reference set, 361 table names were claimed by more than one workflow.

    Steps find their tables by name, so two imports ended up sharing one. That showed up two ways. A step whose columns were not in the table it landed on stopped the workflow with an error naming a column the table does not have. Where the two happened to be compatible, nothing errored and one workflow simply overwrote the other’s results, with both runs reporting success.

    Every import now prefixes its tables with the workflow’s own name, so tool_4_out becomes 03_measure_the_quality_of_data_tool_4_out and two imports cannot collide. Set your own table name prefix during import to override it, or an empty one to get the bare names back. Tables from imports you already ran are not renamed — re-import those workflows to separate them. One case still needs your attention: two files with the same name, names differing only in punctuation or spacing, or a file carrying no name at all all produce the same prefix, so set one yourself for those. See Migrate Alteryx Workflows.

  • A converted Alteryx Batch macro now receives every column the workflow sends it. A macro records the columns it expects to be given, and the conversion built the inside of the macro from only the columns its own steps mention by name — so a column the macro simply carries from its input through to its output was dropped before anything ran, and the columns that did survive were all treated as text whatever type the macro recorded for them. The macro ran to the end either way. A step that needed the dropped column stopped the workflow with an error naming a column nothing had produced. A step that did not need it finished normally and reported success, having worked out its answer from an input that was missing a column — nothing to notice unless you compared the numbers. Numbers and dates arriving as text is the same problem in a quieter form: comparisons and sorting behave differently without anything failing. Macros that repeat until they converge were never affected. Workflows you already imported keep the conversion they were given — re-import those to correct them.

  • A member you disabled can be enabled again. Disabling a member from Identity → Members recorded the time in a format the rest of the platform could not read back, and the only screen that can re-enable someone reads it first — so the Enable action failed with an internal error, and there was no way to reverse a disable. The same unreadable value also broke the member list itself: with one member disabled this way, Identity → Members and the member pickers that use it stopped loading for everyone in the workspace.

    Both work again, and members already disabled this way can be enabled normally — nothing needs to be re-done to them, and no data was lost. Disabled members remained disabled throughout; what was broken was reversing it and listing them.

  • A converted Alteryx DateTime Now step now writes the weekday and month by name. Its default output format asks for both by name, and both came out as the bare letters A and B — a report reading A, 04 B, 2026 where it should read Tuesday, 04 August, 2026. The step reported success and produced a document of an entirely plausible size, so nothing pointed at it until someone read the output. A time-only format was wrong in a quieter way: HH:mm:ss printed the month name where the minutes belong, rendering 14:22:31 as 14:August:31. Both are fixed, and the single-digit hour tokens h and H now render as hours rather than being left in place. Re-run any workflow whose converted DateTime Now step feeds a report or a saved table; already-written values are not corrected retroactively. See DateTime Now.

  • An Access import that cannot read a table now fails and says which one. Importing a Microsoft Access .mdb or .accdb file whose tables could not be read finished green, leaving a table with no columns and no rows behind it. Nothing surfaced until a later step tried to read that table and failed — reporting an error against that step, which pointed the investigation at the wrong place entirely. The import now fails at the import, naming the file and the table it could not read, so the message names the file you need to fix. A file whose tables are genuinely empty still imports, and reports that it loaded no records. See Import Access.

  • AI agents can now build the text, document, spatial and report steps from their documented shape. Asked to create a Text Sentiment, Topic Model, Word Cloud, PDF text, image OCR, Fuzzy Match, XML or JSON parse, any of the spatial or geospatial steps, or any of the report pieces, an agent read the platform’s own description of the step and built it exactly as described — and the step then failed on its first run, every time, because the description named the input-column list differently from the way the step reads it. Thirty-six step types were affected. The description now matches, so a step built from it runs. Steps converted from Alteryx were never affected; they were already built the right way.

  • The Text Sentiment step’s sentence-level scoring is documented. Find sentiment at sentence level — which scores each sentence in a record and returns the average, rather than scoring the whole body at once — has worked all along, but nothing described it, so there was no way to know it was available or what it changed. It is documented now, including the case that makes it look like it does nothing: on records holding a single sentence, the average over sentences is the whole-body score, so the two settings agree. See Text Sentiment.

  • The dimension-member picker now opens reliably and applies to the right rows. Double-clicking a property cell configured to pick a member from a dimension — in the dimension hierarchy grid or a Data Editor grid — needed a second double-click to open when the cell already had a value, and that second click could land the pick on the wrong row further down the grid. Picking a member in an empty cell and clicking Apply silently discarded it (clicking back into the grid instead of pressing Apply happened to work, which is why it went unnoticed), and in some cases Apply cleared the value instead of setting it. In a Data Editor grid, a pick from the picker was discarded outright. All of these are fixed: the picker opens on the first double-click, and Apply and Clear both work reliably on the row you actually edited, in both grids. When several rows are selected, Apply still applies the value to every selected row — that’s intentional multi-row editing, and it now always includes the row you double-clicked. Separately, a property’s Allow Multiple Selections checkbox, in its Dimension Configuration, can now be turned off; it previously reverted to checked no matter what you saved. See Dimension-Type Properties and the Member Picker.

  • Timestamp columns no longer import as empty on Lakehouse v2. Importing a CSV or other delimited text file into a Lakehouse v2 workspace left every timestamp column empty, while the import itself reported success — so nothing pointed at the problem until a later step or a dashboard turned up missing dates. The date format PlaidCloud handed the warehouse was written in the wrong dialect’s format codes, and the two dialects disagree on the most common one in a timestamp: the code PlaidCloud sent for minutes means full month name to Lakehouse v2. Asked to read 22 as a month name, the warehouse matched nothing and returned an empty value for every row rather than reporting an error.

    The same misreading applied to to_timestamp, to_date and to_char anywhere they appear — a transform expression, a view, or a converted Alteryx workflow — where instead of emptying a column it produced visibly wrong text: a HH24:MI:SS format rendered 14:22:31 as 14:August:31.

    This affected any workspace on Lakehouse v2, not only converted Alteryx workflows. Parquet imports were never affected, because they carry their own column types and never build a date format. No other warehouse type was affected. Already-imported rows are not corrected retroactively — check any table you loaded from text files with dates or timestamps, and re-run those imports.

    If you imported a file after this fix was announced and still found empty timestamps, that is why. The correction reached the main service but not the separate, slimmer service that builds most file imports, which was running an older version of the shared code — so an import that ran there behaved exactly as it had before. Both now carry the fix. Re-run any import you ran between the two and check its timestamp columns.

    One related case is not fixed by this: a column whose data type is Time still imports as empty on Lakehouse v2, for a different reason — the warehouse function used to parse it cannot produce a bare time-of-day value at all. Import the column as Timestamp or as Text until that is addressed. See Import CSV.

  • Adding an output column to a Table Lookup or Join step saves again. A column you added by hand started with no data type, and saving the step failed with Update Failed – Internal Server Error — removing the column again was the only way to save. New rows now start as Text, and you can change the type as usual. The same fix covers the Inner, Outer, Anti and Cross Join steps. A step you already saved with a column that has no type runs as well — see the entry above — though setting the column’s Type is still how you say what it should be. See Column Data Type.

  • Exporting a project no longer hides a table whose data could not be read, and a failed export says so. If a table listed in the project has no data behind it, the archive is still written — that table’s data is left out and the export finishes with a message naming the tables it skipped. The archive records them, and restoring it names them again rather than presenting them as complete. Separately, an export that genuinely failed used to report as finished with no file behind it, so the problem surfaced later, usually when someone came to restore the archive; a failure is now reported as a failure. This covers every export type, not only project archives. The export window also names the project it is archiving. See Archive a Project.

  • The AI assistant always draws a diagram as a picture, and won’t invent the numbers in it. A requested diagram occasionally arrived as a block of diagram source code instead of an image; it now renders whichever notation the assistant picks. And a chart or Sankey needs a figure for every bar or band — where the assistant hasn’t been given one, it now asks you for it rather than drawing a plausible-looking value, so a picture that reads as authoritative is not quietly made up. See Using the AI Assistant.

  • The AI assistant can send email and SMS again. Asking it to send a message either failed outright or reported success while sending nothing, so there was no way to make it work. Sending now works, and leaving the recipient out is reported as an error instead of quietly doing nothing. See Using Email.

  • Naming a period column the table doesn’t have now fails clearly. Asking cost-tracing to compare periods using a column that isn’t on the table now says so immediately, naming the column and listing the ones the table does have, so you can correct it in one step. Previously the analysis went ahead and came back reporting only that it couldn’t total the figures — which read as a passing glitch worth retrying, when retrying could never help. Driver what-ifs are checked the same way. For a trace or a driver what-if you can still leave the period column unset and have it detected for you. See Tracing Allocations with an MCP-Connected AI Agent.

  • An AI agent watching a list for changes no longer misses an edit. Agents can ask “has this changed since I last looked?” and get a cheap “not modified” when nothing has. That check was comparing only the identifiers in the list, so renaming or editing a record — without adding or removing one — still came back as “not modified”, and an agent could go on working from a stale copy. It now compares the records themselves. A related fix keeps that answer consistent no matter which server handled the request.

  • A cost-trace answer no longer claims high confidence over a chain it could only partly explain. Tracing a change back through an allocation model can reach stages it cannot pin down — most often a table written by two enabled allocation steps at once, where crediting the change to either would be a guess. Those stages were already listed among the answer’s stated limits, but the headline confidence was taken from the final stage alone, so a four-stage trace with two unexplained stages in the middle still read as “high — clean attribution”. Confidence is now held no higher than medium whenever part of the chain went unattributed, and the answer says how many stages that was and why. The figures themselves are unchanged and still reconcile exactly — it is the claim made about them that was too strong. See Honest Answers.

  • Searching warehouses by name returns the matching warehouses. A name search answered with a bare identifier instead of the matching records, so an agent got neither the details nor a count, and an empty result was indistinguishable from an error. It now returns records like every other search, and matches on any part of the name regardless of case.

  • Republishing a table now clears the cached results of the dashboards reading it. A dashboard caches each chart’s results so repeat views don’t re-query the warehouse. Those cached results were meant to be discarded the moment a workflow run republished the underlying table — but the discard never took effect, so a chart could keep serving pre-refresh numbers until its cached result expired on its own. Republishing now clears them straight away, and the next person to open the dashboard sees the new data without forcing a refresh. See Dashboard Caching.

  • Signing in to dashboards no longer loops for a member who has a duplicate dashboard account. For a small number of people, opening a dashboard landed on the dashboard sign-in page and left it flickering — repainting roughly once a second — without ever reaching the dashboard. Those members had ended up with two dashboard accounts whose email addresses differed only in capitalization, such as Jordan.Smith@example.com and jordan.smith@example.com. Sign-in matched both, could not tell which one was meant, and so treated the person as somebody signing in for the first time; creating the account then collided with the one already there, and the attempt started over from the sign-in page. Sign-in now settles on a single account instead of giving up — an account that is still active, then the one whose capitalization matches exactly, then the oldest — so those members sign in normally. Two dashboard accounts differing only in capitalization can also no longer be created in the first place. This only ever affected members who had a duplicate account of this kind; everyone else signed in normally throughout. If someone reported a flickering or looping dashboard sign-in page, this release fixes it, with nothing for you to clean up.

  • A step whose run was interrupted now reports itself as abandoned, instead of appearing to run forever. When the work behind a step went away mid-run — because someone pressed Stop, or because platform maintenance interrupted it — nothing ever corrected the step’s status. The workflow view kept showing it as running with a duration climbing indefinitely, which reads as an extremely slow step: in the case that prompted this, a step that takes three seconds displayed as running for over twenty minutes.

    Such a step is now marked abandoned, with an explanation in its status tooltip, and its duration stops. An open workflow view refreshes on its own, so it corrects itself without a manual reload. An abandoned step did not complete and produced no output — it is not a slow step and not a data problem. You can either Resume the run, which runs the abandoned step again, or re-run the whole workflow. See Follow a Step’s Status.

  • Resume picks a workflow back up where it stopped, including inside called workflows. A run that failed several levels deep — a workflow calling a workflow, or a loop step working through its iterations — restarted the first called workflow from its opening step instead of returning to the point of failure, repeating everything in between. Resume now returns to the step that failed, at whatever depth it sits, and a loop step resumes the interrupted iteration and skips the iterations that already completed. See Run a Workflow.

  • Resume no longer re-runs completed steps on parallel and Advanced workflows. On both, Resume restarted the whole workflow, so every step that had already succeeded ran a second time — including any sub-workflows they called. Both now re-run only the step or node that failed and whatever was still waiting on it. If you had been using Resume on a parallel workflow as a way to re-run everything, use Run All instead. See Run a Workflow.

  • Resuming a Run Selected run keeps its selection. Resuming a run that had been scoped to a chosen set of nodes on the Advanced canvas widened it to the whole workflow. The original selection is now preserved. See Advanced Workflows.

  • Saving a security form with nothing selected now tells you nothing changed. Assigning members to a group, or groups to a member, and saving with an empty list reported success while making no change — and on the member form it could instead remove every group that member had. An empty list now leaves the assignment alone and says so. See Managing Security Groups and Assignments.

  • Pre-built queries sent to the platform are now rebuilt under a restriction instead of being trusted. Several Analyze operations — allocate, melt, pivot, update, delete, table exports and view definitions — accept a query that was assembled elsewhere and sent along with the request. The platform used to reconstruct whatever arrived, which meant a crafted request from anything able to reach those operations could have run code inside the server. Such a request now rebuilds only the database-query pieces a genuine query is made of, and anything else is refused with an invalid-argument error. Queries you build in the product are unaffected, and an export that supplies plain SQL rather than a pre-built query works exactly as before.

  • A pre-built query can no longer carry SQL of its own. The change above checks what kind of pieces a pre-built query is rebuilt from, but not the text those pieces hold — so a crafted request could still hand the warehouse a statement of its own choosing, reading a table the query never named. That text is now checked too: a literal SQL fragment must be a single value rather than a statement, and a name that asks to skip quoting must be an ordinary identifier.

    Queries you build in the product are unaffected, as are column names containing spaces, dots or quotation marks — those are quoted for you and always were. Two expression shapes stop working, both in sqlalchemy.literal_column. Text that is a subquery is now refused, because that is the shape that reads a table the query never declared — build it with sqlalchemy.select(...) instead, .scalar_subquery() for a single value or .subquery() for a table to select from, both of which the expression editor already accepts. And text whose outermost operator is OR is refused, because a condition added after it binds to only half of it; put brackets round it, (a OR b), and it works as before. See Reading Another Table From an Expression.

  • Editing a security group’s permissions no longer removes the permissions you don’t hold yourself. Anyone who was not a workspace administrator silently stripped every permission on that group they could not grant themselves — just by opening the permission matrix and saving it, even without changing anything. Workspace administrators were unaffected, which is why this looked like permissions disappearing at random for some people and never for others, and why a permission held by only a few, such as Panel app management, would drop off repeatedly and have to be re-added. Those permissions are now left untouched.

    Review any security group that a non-administrator has edited and confirm its permissions are what you expect — a permission removed this way was removed for everyone in the group. See Managing Security Groups and Assignments.

  • A permission you do not hold can no longer be granted through the permission matrix. The form only ever offered the permissions you are allowed to control, but a request naming others was accepted anyway, so someone able to manage users could grant a group — and through it themselves — broader access than they held. Permissions being granted are now checked against your own.

  • Permission and membership changes are recorded in the security log. Changing a group’s permissions or members, or a member’s groups, previously left no record unless the Git server sync failed, so a permission that changed could not be attributed to anyone afterwards. Every change is now logged with what was granted and what was revoked. See Performing a Security Audit.