Exception reference

Every Ariadne-specific exception extends AriadneException, so you can catch the whole family with a single handler. (Argument-validation errors still surface as the standard JDK IllegalArgumentException — those indicate programmer mistakes, not runtime failures.)

import dev.cjfravel.ariadne.exceptions._

try {
  index.update
} catch {
  case e: AriadneException => // handle any Ariadne error
}
ExceptionWhen it's thrown
SchemaNotProvidedExceptionCreating a new index without a schema.
SchemaMismatchExceptionSource schema changed and allowSchemaMismatch is false.
FormatMismatchExceptionFormat passed at construction doesn't match what's stored.
IndexNotFoundExceptionRemoving or referencing an index that doesn't exist.
IndexNotFoundInNewSchemaExceptionNew schema is missing a previously indexed column.
ColumnNotFoundExceptionReferencing a column that's not in the schema or indexes.
IndexLockExceptionLock acquisition timed out (default 1 hr).
MetadataMissingOrCorruptExceptionIndex metadata is unreadable — delete and re-create.
MissingFormatExceptionCreating a new index without a format.
MissingSchemaExceptionSchema field is null in metadata (corrupted file).
SchemaParseExceptionStored schema string can't be parsed.
FileListNotFoundExceptionRemoving a file list that doesn't exist.
UnsupportedStorageFormatVersionExceptionThe index declares a newer storage_format_version than this Ariadne build supports.
UnsupportedMetadataVersionExceptionThe index declares a newer metadata_version than this Ariadne build supports.
UnsupportedJoinTypeExceptionThe requested join type depends on unmatched index-side rows — see Supported join types.

Persisted-index compatibility

This Ariadne build supports indexes created by 0.0.1-alpha-37 through 0.1.10-beta. Queries and other operational methods migrate supported older layouts under the update lock; plain Index(name) construction remains read-only. Indexes written by later releases may require a newer library.

FailureRecovery
UnsupportedStorageFormatVersionException or UnsupportedMetadataVersionExceptionUpgrade Ariadne to a version that supports the declared storage_format_version or metadata_version. Do not downgrade or edit version markers manually.
Index predates 0.0.1-alpha-37Remove and rebuild the index from source data with the current library.
Migration fails physical verificationCorrect the reported missing source, filesystem, or schema problem and retry. The version is not advanced on failure.
Metadata is corrupt or a previously indexed column was removedRestore a known-good index directory or remove and rebuild from source.

Ariadne does not silently rebuild, downgrade, or return incomplete query results when it encounters an unsupported or unverifiable layout.

FetchFailedException during joins

Large indexes can produce enormous intermediate DataFrames during the array explode step, which overwhelms Spark's shuffle. Spread the work across more partitions:

spark.conf.set("spark.ariadne.indexRepartitionCount", "500")

// If your data files are also very large
spark.conf.set("spark.ariadne.repartitionDataFiles", "true")

Typical values for indexRepartitionCount: 100–500, depending on cluster size and data volume. Don't set it for small indexes — the extra shuffle hurts more than it helps.

IndexLockException

Two causes:

  1. Another job is legitimately holding the lock. Wait for it to finish.
  2. A previous job crashed mid-operation and left a stale lock.

Stale locks auto-heal after spark.ariadne.lockTimeout seconds (default 30 min). If you're certain no job is running and don't want to wait, delete the lock file directly:

{storagePath}/{indexName}/.update.lock
{storagePath}/{indexName}/.filelist.lock

Don't delete locks blindly. If you nuke a lock while a job is actually holding it, two writers will race and you'll get corrupted Delta state. Confirm no job is running first.

Out-of-memory during update

High-cardinality columns produce large in-memory arrays during the build phase. Two levers:

  1. Lower the large-index threshold so high-cardinality columns get split into separate Delta tables earlier:
    spark.conf.set("spark.ariadne.largeIndexLimit", "100000")
  2. Switch to bloom indexes for the offending column — a bloom filter is sized from that file's own distinct count (roughly 1.2 bytes per distinct value at the default 1% FPR), so memory stays proportional to cardinality rather than growing with the full value array:
    index.addBloomIndex("high_cardinality_col", fpr = 0.01)

MetadataMissingOrCorruptException

The metadata.json file for the index is missing or unparseable. There's no in-place repair — remove and rebuild:

Index.remove("myIndex")
val index = Index("myIndex", schema, "parquet")
// re-add indexes and files, then update

SchemaMismatchException

Your source data schema changed since the index was built. Reconnect with the new schema and opt in to the mismatch:

val index = Index("myIndex", newSchema, "parquet", allowSchemaMismatch = true)

Caveat: all previously indexed columns must still exist in the new schema. If a column was renamed or removed, you'll get IndexNotFoundInNewSchemaException and need to remove and rebuild.

Joins log 0% pruning

The pruning-metrics line shows loaded N of N files — every file was read. Common causes:

Enable debug logging for a per-stage breakdown:

spark.conf.set("spark.ariadne.debug", "true")