Skip to content

Computed Join Troubleshooting

This page lists common errors you can hit when creating, editing, or running a Computed Join. Each section names the user-visible message, the underlying cause, and the resolution. Use your browser search to find the exact text of the message you saw.

Duplicate container name

Container with name: '<name>' already exists in datastore id: <id>

Cause: A container with this name already exists on the parent datastore, including containers that were deleted and not yet purged.

Resolution: Pick a unique name, or rename the conflicting container.

403 Forbidden on Create, Edit, or Delete

The exact wording varies by action and ownership:

You don't have permission to create this computed asset. You must either have [Editor] permission on the datastore, or have [Author] permission and be the owner of the asset
Only the computed container owner (Author) or an Editor can modify this container
Only the computed container owner (Author) or an Editor can delete this container
Only the computed container owner (Author) or an Editor can modify these settings
Authors cannot change computed asset ownership; only an Editor can reassign the owner

Cause: Your team permission on the datastore the Computed Join belongs to is below what the action requires (the left datastore in pairwise mode, the first source's datastore in SQL mode). Editors can act on any Computed Join; Authors can act only on the Computed Joins they own, and cannot transfer ownership even when they are the current owner.

Resolution: Ask a datastore Editor (or an Admin) to perform the action, transfer ownership to you, or grant you the Editor team permission. See Computed Join Permissions for the full matrix.

Computed Join used as input

Left/Right container id: <id> of type computed_join not supported

Cause: The chosen left or right container is another Computed Join. Computed Joins cannot be used as inputs to another Computed Join.

Resolution: Materialize the input join's result as a Computed Table, then use that Computed Table as the input. See Supported Inputs.

Input container not profiled

Left/Right container id: <id> has not been profiled

Cause: The chosen container has never been profiled. A Computed Join requires both inputs to be profiled first.

Resolution: Profile the input container, then retry creating the join.

Mismatched join field types

Join field types must match: left field '<x>' is <type>, right field '<y>' is <type>

The message above appears when you save or validate. If the types drift apart after the join is created (a field's type changed upstream), the next profile or scan first tries to widen both sides to a shared type, and fails only when there is none:

Join keys have incompatible types: <left field> (<type>) vs <right field> (<type>)

Cause: The chosen join fields on the left and right have incompatible data types (for example, string vs decimal).

Resolution: Where possible, cast one side using a Computed Field on the input container so the joined fields share a type. If a Computed Field isn't a fit for the input type, pick a different pair of fields whose types already match, or transform the data upstream.

DISTINCT in the Select Expression

Spark SQL select clause can not use the distinct() function, consider using the field expression `explode(collect_set(your_field_name)) as distinct_field_values` for your use case

Cause: The Select Expression includes any form of DISTINCT: the bare keyword, DISTINCT(col), aggregate forms like COUNT(DISTINCT col), SUM(DISTINCT col), APPROX_COUNT_DISTINCT(col), or multi-column variants.

Resolution: Replace DISTINCT col with explode(collect_set(col)). Add a GROUP BY only if your Select Expression also includes columns that are not aggregated. See Best Practices.

Semicolon in the Select or Filter clause

Multi-statement SQL detected in SELECT clause. Only expressions are allowed. Clause prefix: <prefix>

Cause: The clause contains a semicolon, suggesting multiple SQL statements. Only a single expression or predicate is allowed. The WHERE clause variant ends with Only boolean expressions are allowed, and the LATERAL VIEW variant ends with Only generator expressions are allowed.

Resolution: Remove the semicolon.

Validation timeout

Timed out after waiting <N> seconds to validate your container configuration

Cause: Validating the join definition against the input containers took longer than the configured timeout.

Resolution: Retry. If it keeps timing out, simplify the query or narrow each side by materializing a filtered Computed Table or Computed File and using it as the input. If the timeout persists, contact your administrator. (API callers can raise the timeout_seconds query parameter on POST /containers/validate up to 300 seconds, see the API reference.)

Join field no longer exists

Join field '<field>' not found in left container '<container>'
Join field '<field>' not found in right container '<container>'

The pair above appears when you save or validate the join. If the field disappears after the last save, the next profile or scan fails with a shorter wording that names only the side and the container:

Left side join field not found in <container>
Right side join field not found in <container>

Cause: The configured join field no longer exists in the input container (renamed or removed upstream).

Resolution: Edit the Computed Join, pick a current field from the affected side, and save.

Select Expression references a missing column

Valid column names could not be parsed from the select clause [<your clause>]. Did you forget to escape special characters?

Cause: The Select Expression references a column that no longer exists in the joined output. This usually happens when an upstream input container had a field renamed or dropped, and the Computed Join's Select Expression still points to the old prefixed name. The platform validates the Select Expression on every save and on each scan or profile.

Resolution: Open the failing Computed Join and update the Select Expression to use the current prefixed field names from the left and right inputs (left prefix + underscore + original field name, same for the right side). Save again to retrigger validation. If the field was intentionally renamed upstream, rebuild the Select Expression around the new name.

Input container marked as Unloadable

Container '<name>' is marked as Unloadable. No attempt was made to load it due to multiple consecutive failures in prior operations

Cause: The input container failed three consecutive scan or profile operations and was marked Unloadable. Qualytics short-circuits any join that uses it until the status clears.

Resolution: Open the input container and follow the recovery steps for its type: run a Sync for tables, views, and file patterns, or Edit + Validate + Save for Computed Tables and Computed Files used as inputs. See Scan Troubleshooting for the full procedure.

Where Clause references a missing column

[UNRESOLVED_COLUMN] A column, variable, or function parameter with name '<col>' cannot be resolved.

Cause: The Where Clause references a column that no longer exists in the joined output. This is the Where Clause counterpart to the Select Expression failure above. Because the Where Clause path does not have a dedicated friendly message, the user sees the raw SQL analyzer error.

Resolution: Open the failing Computed Join and update the Where Clause to use the current prefixed field names. The error often includes a suggestion with the closest matching column name. Save again to retrigger validation.

Input container too large for one load pass

In pairwise mode the message names a side:

Your deployment is not large enough to load <left|right> container into a single chunk. Contact your administrator to provision additional capacity or limit the scope of your request before trying again

In SQL mode it names the source instead:

Your deployment is not large enough to load source '<alias>' (<container name>) of <join name> into a single chunk. Add or tighten a per-source filter, reduce the number of sources, or contact your administrator to provision additional capacity before trying again.

Cause: One input on its own holds more data than the deployment can load in a single pass during the join.

Resolution: Narrow that input. In pairwise mode, materialize a filtered Computed Table or Computed File and use it as the input. In SQL mode, add or tighten that source's Filter Clause. Projecting fewer columns helps as well. If none of that is enough, request additional capacity from your administrator.

GROUP BY validation failure (missing column)

GROUP BY clause validation failed for <name>

Cause: The Select Expression includes columns that are neither aggregated nor present in the Group By Clause.

Resolution: Either add the column to the Group By Clause, or wrap it in an aggregation function (SUM, MAX, COUNT, etc.).

GROUP BY validation failure (column not found)

Column not found when applying groupByClause for <name>. Check that all columns in selectClause and groupByClause exist after the join.

Cause: A column referenced in the Group By Clause does not exist in the joined result. This usually happens when prefixes don't match the column alias.

Resolution: Inspect the prefixed column names produced by the join (left prefix + underscore + original field name, same for the right side) and update the Group By Clause to reference the exact prefixed names.

GROUP BY without aggregations

Invalid groupByClause for <name>: selectClause must include aggregations (SUM, AVG, MAX, MIN, etc.) for non-group-by columns

Cause: A Group By Clause was provided, but the Select Expression contains no aggregation functions.

Resolution: Either add at least one aggregation function (SUM, MAX, COUNT, etc.) to the Select Expression, or remove the Group By Clause.

Duplicate column names (prefix collision)

The definition of <name> produced the following duplicate column names: <list>

Cause: Two columns in the joined output resolve to the same name after prefixing. The most common trigger is identical Left Prefix and Right Prefix (defaults are left and right; if both are changed to the same value, every shared column name collides). Other triggers: a hand-aliased column in the Select Expression collides with a prefixed one, or the same alias is reused. The configuration is accepted at save time and only fails when validation runs.

Resolution: Open the join configuration and set distinct values for Left Prefix and Right Prefix. If the prefixes are already distinct, find the colliding pair in the Select Expression and either add an explicit AS <alias> to one of them, or remove the duplicate. Save again to retrigger validation.

SQL mode: too few or too many sources

A SQL-mode computed join requires at least 2 sources
A SQL-mode computed join supports at most 10 sources; got <n>

Cause: A SQL-mode join was submitted with fewer than 2 sources, or with more than 10. Both checks run on Create, on Update, and when you click Validate.

Resolution: Declare at least 2 sources. If you hit the upper limit, remove sources, split the work across joins, or fold part of the logic into a Computed Table. The maximum of 10 is a platform limit and cannot be raised.

Where these messages appear

The form disables Add New Source at 10, so the upper-limit message only shows up when the join is created outside the form, through the API, the CLI, or AgentQ. AgentQ wraps it, so there it reads Failed to create computed join: A SQL-mode computed join supports at most 10 sources; got 11. In the app, the message appears in an alert headed Failed to create, Failed to update, or Failed to validate, depending on which action you took.

If a request leaves the source list out altogether instead of sending a short one, it fails earlier with a different message:

SQL-mode computed join requires both `query` and `sources`; missing: sources

SQL mode: invalid or duplicate source alias

Source alias '<alias>' is not a valid identifier (must match ^[A-Za-z_][A-Za-z0-9_]*$)
Duplicate source alias: '<alias>'

Cause: A source alias is not a simple identifier, or two sources share an alias.

Resolution: Give each source a unique alias that starts with a letter or underscore and contains only letters, digits, and underscores.

SQL mode: source is a Computed Join

Source container id: <id> of type computed_join is not supported as a join source

Cause: One of the declared sources is itself a Computed Join, which is not allowed in either mode.

Resolution: Materialize that join's result as a Computed Table and use the Computed Table as the source. See Supported Inputs.

SQL mode: source not profiled

Source container id: <id> has not been profiled

Cause: A declared source has never been profiled. Sources must be profiled before they can be used.

Resolution: Profile the source container, then retry.

SQL mode: query is not valid Spark SQL

Computed join query is not valid Spark SQL: <parser message>

Cause: The query could not be parsed as Spark SQL, so none of the deeper checks (read-only statement, table references, functions) ran. The parser's own message follows the colon and points at the offending token. A query left empty is reported as Computed join query is empty instead.

Resolution: Fix the syntax error the parser points at, then validate again. The query must be a single Spark SQL statement (CTEs are allowed) over the declared source aliases.

SQL mode: query is not a read query

Computed join query performs an INSERT; only read queries are permitted

Cause: The query contains a statement that modifies data (INSERT, DELETE, UPDATE, or MERGE), a script transformation, or another command. Only read queries are accepted; the exact wording names the statement found.

Resolution: Rewrite the query as a single SELECT (with optional CTEs) over the declared source aliases.

The full messages quote your query

This message, the prohibited-function message, and the two table-reference messages below end with Query prefix: followed by the first 200 characters of your query. The quotes on this page leave that part out.

SQL mode: prohibited function

Computed join query calls prohibited function 'reflect'. Functions that execute arbitrary JVM code (reflect, java_method) are not permitted

Cause: The query calls reflect or java_method, which can execute arbitrary code.

Resolution: Remove the call and express the logic with standard Spark SQL functions.

SQL mode: qualified or unknown table reference

Computed join query references qualified table '<catalog.db.table>'; SQL-mode joins may only reference their declared source aliases (<aliases>)
Computed join query references unknown relation '<name>'; it is not one of the declared source aliases (<aliases>) or a CTE in the query

Cause: The query uses a qualified or catalog table name, or references a name that is neither a declared alias nor a CTE defined in the query.

Resolution: Reference each source by its alias only. Add any intermediate result as a CTE inside the query, or declare it as a source.

SQL mode: source alias collides with a CTE name

Computed join source alias(es) collide with CTE name(s) defined in the query: <name>. Rename the source alias or the CTE.

Cause: A source alias has the same name as a CTE defined in the query.

Resolution: Rename either the source alias or the CTE so the names are distinct.

SQL mode: combined source size exceeds join capacity

The combined size of the <join name> join sources (~<total>MB across <count> sources) exceeds this deployment's join capacity (<ceiling>MB). Add or tighten per-source filters, reduce the number of sources, or contact your administrator to provision additional capacity.

Cause: Before running your query, Qualytics adds up the loaded size of every declared source and compares the total against the deployment's join capacity. Because this limit is about the total, it can stop a join in which no single source is large enough to trip the per-source limit.

Resolution: Add or tighten the per-source Filter Clauses so less data is read, join fewer sources at a time, or ask your administrator to provision additional capacity.

This limit never fires when you click Validate

Validate runs your query against empty data, so nothing is loaded and this limit can never trip there. A join that is over the combined limit still validates and saves cleanly, and only fails later, the first time a profile or scan actually runs it. When you are joining several large sources, read a clean Validate as confirmation that the SQL is correct, not that the join will fit in memory.

SQL mode: a source failed to load

Source '<alias>' (<container name>) of <join name> failed to load: <reason>
Source '<alias>' (<container name>) of <join name> failed to prepare: <reason>

Cause: One declared source could not be read. The reason comes from the underlying datastore, and shows as unknown error when the datastore reported none.

Resolution: Confirm the source container still exists and its datastore is reachable, then retry. The alias in the message tells you which source to look at, which matters when the join declares several.

SQL mode: timed out waiting for sources to load

Timed out after <seconds>s waiting for the sources of <join name> to load

Cause: Qualytics reads the declared sources in parallel and waits for all of them to finish. This is a different timeout from Validation timeout above: it covers reading the source data, not checking the definition.

Resolution: Add or tighten per-source Filter Clauses so there is less data to read, or declare fewer sources. If the sources are healthy and the volume is expected, ask your administrator about capacity.

SQL mode: invalid per-source Filter Clause

The filter clause for source '<alias>' (<container name>) is invalid: <reason>

A malformed clause is caught earlier, by messages that do not name the source:

Multi-statement SQL detected in WHERE clause. Only boolean expressions are allowed. Clause prefix: <clause>
WHERE clause did not parse as a valid SELECT statement. Clause prefix: <clause>
WHERE clause validation failed (parse error): <parser message>. Clause prefix: <clause>

Cause: A per-source Filter Clause is not a plain boolean expression, or it references something that cannot be resolved against that source's columns. The first message carries the SQL analyzer's own wording, so a misspelled column arrives as an unresolved-column error. All of these appear when the definition is validated.

Resolution: Correct that source's Filter Clause so it is a single boolean expression over columns that exist on that source. Write it as you would the text after WHERE, without the keyword itself and without a trailing semicolon. In the messages that quote a Clause prefix, only the first 100 characters of your clause are shown, followed by ....

Incremental field missing from the join output

Incremental field '<field>' was not found among the output columns of <join name>. Update the container's incremental identifier to one of its output columns.

Cause: The join has an Incremental Field configured, but the joined result no longer produces a column with that name. This usually follows an edit that stopped projecting the column from the Select Expression (pairwise) or the query (SQL mode), or a prefix change that renamed it.

Resolution: Edit the join so the output produces that column again, or point the Incremental Field at one of the current output columns (through the container's Settings modal, or the API's incremental_identifier object). See How It Works ยท Incremental Loading.

Connection timed out to the datastore

Connection timed-out after retrying 3 times

Cause: One side of the join could not establish a connection to the source datastore after three retry attempts with exponential backoff.

Resolution: Confirm the datastore is reachable from your Qualytics deployment (network, security group, credentials, datastore availability). If the datastore is healthy, retry. If retries keep failing, contact your administrator.

Container referenced by quality checks (delete)

Cannot delete container: <id> because it is referenced by the following data quality checks

Cause: Quality checks elsewhere reference this Computed Join (for example, an Aggregation Comparison, Exists In, Not Exists In, or Data Diff check using the joined output).

Resolution: Delete or re-target the referencing quality checks, then retry the delete.

Container is input to a Computed Join (delete)

Container id: <id> is being used by the following computed join containers: [<join ids>] that must be deleted first
Container id: <id> is being used as a source by the following computed join containers: [<join ids>] that must be deleted first

Cause: You are trying to delete a base container or computed asset that one or more Computed Joins reference as input. The two messages differ by three words, and those words tell you which kind of join is blocking you. With as a source, a SQL-mode join is using the container as one of its aliased sources. Without them, a pairwise join is using it as its left or right side.

Resolution: Delete the Computed Joins listed in the message first, then the input container. The delete dialog shows the message below a Failed to Delete heading that ends with the container type (for example, Failed to Delete Table).

Messages that look almost identical

Two other blockers are worded so similarly that searching for "is being used by the following" will match them as well, and neither is about Computed Joins. A container feeding a Computed File reports is being used by the following computed files: instead. Deleting an entire datastore whose containers feed joins elsewhere reports:

The datastore cannot be deleted because it is referenced by computed join containers from other datastores

When a container trips more than one blocker at once, the separate sentences are joined with a semicolon into a single message.

Removed fields warning on Save

This change will mark the following fields as missing, preserving their quality checks and anomalies. Set force_drop_fields=true to proceed.

Cause: The edit removes fields that have active quality checks or anomalies, because the pairwise Select Expression or the SQL-mode query stopped projecting them. The server returns the message above; the UI surfaces a shorter "Fields will be marked as missing" banner with the same intent.

Resolution: Adjust the Select Expression (pairwise) or the query (SQL mode) to keep those fields, or click Proceed Anyway to apply the edit. The dropped fields are marked missing, and their quality checks and anomalies are preserved until they reappear in a future edit.