Table of Contents

Enum EdgeErrorCode

Namespace
Qavren.Edge
Assembly
Qavren.Edge.Core.dll

Stable, programmatically handleable error identity for every EdgeException.

public enum EdgeErrorCode

Fields

Unknown = 0

No error code was set. The default enum value; never assigned by a thrown EdgeException.

DuplicateDatabaseName = 1001

Two databases were registered under the same name — either two AddSqlite calls collided, or AddMigration for a name was called before its matching AddSqlite.

Give each database a distinct name, and call AddSqlite before adding migrations against it.

NoNativeProviderRegistered = 1002

No SQLite native provider was registered before the Edge builder tried to open a database.

Reference Qavren.Edge.Sqlite.Native and call UseSqliteNative(), or reference Qavren.Edge.Sqlite.Native.Cipher and call UseSqliteNativeCipher().

MultipleNativeProvidersRegistered = 1003

More than one SQLite native provider is registered at once, so the builder cannot tell which one should back the database.

Reference exactly one of Qavren.Edge.Sqlite.Native or Qavren.Edge.Sqlite.Native.Cipher — never both in the same app.

EncryptionKeyWithoutCipherProvider = 1004

A database has an encryption key configured but the registered native provider has no cipher codec, or a rekey was attempted on a database that is not encrypted.

Reference Qavren.Edge.Sqlite.Native.Cipher and call UseSqliteNativeCipher() instead of UseSqliteNative() whenever a key is configured.

EncryptionKeyMissing = 1005

A cipher-capable native provider is registered for a database whose configuration requires an encryption key, but none was supplied.

Set the key on the database's options (AddSqlite(o => o.Key = ...)) before it is opened.

NativeLoadFailed = 2001

The native SQLite library (qedge_sqlite3 / qedge_sqlcipher) could not be loaded for the current runtime identifier.

Raised as EdgeNativeException; inspect its ProbedPaths and RuntimeIdentifier to confirm the native package's output for that RID was actually staged beside the app binary.

NativeVerificationFailed = 2002

The native library loaded, but a startup verification check against it failed — the binary is present but is not the one Qavren.Edge expects.

Confirm the native binary was not swapped, truncated, or built from a mismatched native/versions.json pin; reinstall or rebuild the native package for the target RID.

MigrationFailed = 3001

A migration threw while running. The database is left at the last successfully applied user_version; the failed migration was not partially committed.

Fix the migration named in the exception message and rerun; the database remains usable at its prior version in the meantime.

MigrationVersionConflict = 3002

The same migration version number was registered twice for one database.

Give each AddMigration call for a database a unique, ascending version number.

DatabaseKeyRejected = 4001

A SQLCipher database refused the key it was opened with.

Confirm the key is correct, or that the file being opened is actually a SQLCipher database and not a plain SQLite file.

OnnxEnvironmentAlreadyCreated = 5001

Another library created the ORT environment first. Logged, never thrown.

OnnxSessionCreationFailed = 5002

Every execution provider, including the CPU fallback, failed to append, or the native ONNX Runtime library itself is missing.

Carries the RID, the probed path and every execution-provider attempt in EdgeNativeException's shape; confirm the ONNX Runtime native for the current RID is present and loadable.

OnnxModelSignatureMismatch = 5003

The loaded graph declares an input the caller cannot supply.

The exception lists both the graph's declared input names and the names Qavren.Edge can produce; check for a mismatched model file or preset id.

OnnxExecutionProviderRequired = 5004

An execution provider listed in the session policy's Required set failed to append, and the policy does not allow falling through to CPU for that provider.

Either remove the provider from Required, or fix why it cannot append (a missing native asset, or an OS version below the provider's floor).

OnnxInsufficientMemory = 5005

The device's available memory is below the configured budget for the preset being loaded, checked before new InferenceSession runs.

Carries both the required and available byte counts; use a smaller preset (an int8 variant), free memory before loading, or raise the configured memory budget.

OnnxUnsupportedRuntime = 5006

osx-x64 and any RID with no ORT native.

OnnxStaticShapesUnpinned = 5007

RequireStaticInputShapes set with no FreeDimensionOverrides.

ModelNotRegistered = 5051

The requested model id was never declared by any registered model source.

Register the model before requesting it; check for a typo'd model or preset id.

ModelNotProvisioned = 5052

The model is registered, but its files have not yet been downloaded or staged to local storage.

Provision the model explicitly, or let first-use auto-provisioning run, before using it.

ModelDownloadFailed = 5053

Downloading the model's bytes failed — network failure, a non-2xx/206 response, or a server that ignored a Range request and forced a restart that then also failed.

Check connectivity to the model source and retry; a server that consistently ignores Range restarts the download from scratch every time by design.

ModelHashMismatch = 5054

The SHA-256 of a downloaded or staged file does not match the manifest, even after the one automatic retry.

Delete the cached file and re-download; confirm the manifest's recorded hash still matches the current revision of the source.

ModelAssetMissing = 5055

A file the model's manifest requires (for example vocab.txt) is not present on disk at load time.

Re-provision the model bundle; confirm the model root directory was not partially deleted or moved.

ModelInsufficientDiskSpace = 5056

Free disk space is short of the remaining bytes to download plus a safety margin, checked before the download starts.

Free disk space, or choose a smaller preset (an int8 variant).

TokenizerAssetMissing = 5101

A file the tokenizer needs (for example vocab.txt) is missing for the preset being loaded.

Re-provision the model/tokenizer bundle; verify the configured model root path.

TokenizerKindUnsupported = 5102

The requested tokenizer kind is not implemented yet — today this is any multilingual preset that needs a Unigram/SentencePiece tokenizer.

Use one of the shipped WordPiece/BERT-tokenized presets until multilingual support lands (see ADR 0006).

EmbeddingDimensionMismatch = 5103

The embedding generator's actual output dimension does not match the dimension declared elsewhere — a preset's stated dimension, or a DefaultModelDimensions override.

Confirm the configured preset and any dimension override agree with the preset's real output size.

EmbeddingPresetNotFound = 5104

The requested preset id does not match any of the shipped EmbeddingPresets.

Check the spelling of the preset constant; only the four shipped presets exist in v1.

EmbeddingInputTooLong = 5105

The input text, once tokenized, exceeds the sequence length the generator is configured to accept.

Shorten the input or chunk it into smaller pieces before embedding.

VectorCollectionNotFound = 5201

The requested collection name has no matching table.

Call EnsureCollectionExistsAsync first, or check the collection name for a typo.

UnsupportedKeyType = 5202

The [VectorStoreKey] property's CLR type is not one the provider supports.

Use one of the four supported key types — int, long, string or Guid.

UnsupportedPropertyType = 5203

A data or vector property's CLR type has no SQL mapping in this provider.

Change the property's type to a supported one, or correct its [VectorStoreData]/[VectorStoreVector] attribute.

UnsupportedDistanceFunction = 5204

The DistanceFunction set on [VectorStoreVector] is not one vec0 supports.

Use one of the three supported values — CosineDistance (the default), EuclideanDistance or ManhattanDistance.

VectorDimensionMismatch = 5205

The embedding generator's dimension does not match the vector property's declared dimension.

Make [VectorStoreVector(dims)] match the configured embedding generator's actual output dimension.

FullTextPropertyMissing = 5206

HybridSearchAsync was called on a record type with no [VectorStoreData(IsFullTextIndexed = true)] property.

Mark at least one text property IsFullTextIndexed = true, or call VectorSearchAsync instead of hybrid search.

EmbeddingGeneratorMissing = 5207

A string-source vector property needs an IEmbeddingGenerator, and DI resolution (including the non-generic fallback) found none.

Call AddOnnxEmbeddings (or otherwise register a matching IEmbeddingGenerator) before AddVectorStore.

MultipleVectorPropertiesUnsupported = 5208

The record type declares more than one [VectorStoreVector] property; v1 supports exactly one.

Keep exactly one vector property per record type.

NullableVectorProperty = 5209

A vector property was declared nullable — rejected at model build time rather than left as a runtime null-means-skip trap on upsert.

Make the vector property's type non-nullable.

KnnLimitExceeded = 5210

top + Skip exceeds SQLITE_VEC_VEC0_K_MAX, vec0's own cap on k for a single KNN query. Raised before the query reaches SQLite.

Reduce top and/or Skip so their sum stays within vec0's k limit (4096).

SqliteVersionTooOld = 5211

The SQLite build in use predates the version the vec0/FTS5 features this provider depends on require.

Use the bundled qedge_sqlite3 native (Qavren.Edge.Sqlite.Native) rather than an external or OS-provided SQLite.

VectorStoreOperationFailed = 5212

A SqliteException surfaced during a store operation and was wrapped so callers get one exception type across every operation.

Inspect the wrapped SqliteException (InnerException) for the underlying SQL error.

ReservedColumnName = 5213

A property claims the reserved "_rowid" storage name.

TokenCounterMissing = 6001

No IChunkTokenizer is resolvable at startup — there is deliberately no chars/4 fallback.

Call AddOnnxIngestion() to use the tokenizer, or register one with UseChunkTokenizer(...) / EdgeTokenCounter.CreateWordPiece(...).

IngestionCollectionNotConfigured = 6002

RunAsync, PruneAsync, GetStatusAsync, RemoveSourceAsync or RemoveDocumentAsync named a collectionName that no AddIngestion call configured.

Call AddIngestion for that collection, or pass null to use the single configured one.

IngestionChunkBudgetInvalid = 6003

The resolved chunk budget arithmetic is invalid, checked at startup once the resolved IChunkTokenizer is known.

Adjust ChunkOptions (OverlapTokens, MinTokens, HeadingPathTokenBudget) or the model profile so the overhead, overlap and minimum token settings stay within the model's max sequence length.

IngestionDuplicateExtractorId = 6004

Two IDocumentExtractors registered in the DocumentExtractorRegistry composition declared the same Id.

Give each extractor a distinct Id, or remove the duplicate registration.

IngestionOptionsInvalid = 6005

A tokenizer-independent ingestion option failed validation at registration.

The exception message names the offending value(s) — adjust IngestionOptions accordingly before the next start.

IngestionCollectionDimensionMismatch = 6006

The embedding generator's EmbeddingGeneratorMetadata.DefaultModelDimensions disagrees with the collection's declared dimensions.

Use a generator whose dimensions match the collection, or reconfigure the collection to match the generator.

IngestionMigrationVersionConflict = 6007

A second AddIngestion call was made for the same collection.

Call AddIngestion once per collection; remove the duplicate call.

IngestionRunAlreadyActive = 6008

IngestionPipeline.RunAsync was called while a run is already active on the same pipeline, or a run and a removal (PruneAsync, RemoveSourceAsync, RemoveDocumentAsync) were asked to overlap.

Await the active run's IngestionRunResult before starting another run or a removal on the same pipeline, or use a separate pipeline/collection.

IngestionRecipeChanged = 6009

The recipe hash (chunking and extraction configuration) differs from the one the state store last recorded, and StrictRecipe is set.

With the default StrictRecipe = false this is never thrown — affected documents are silently re-indexed and logged instead; with StrictRecipe = true, restore the prior configuration or accept the new recipe and re-run.

IngestionRunAborted = 6010

AbortAfterConsecutiveErrors (20) consecutive document failures were reached in one run.

Inspect the inner exception and the per-document failures in IngestionRunResult.Documents — twenty in a row usually means a systemic problem, not one bad file.

IngestionCollectionSchemaMismatch = 6011

The migration's collection DDL differs from the runtime store's BuildCreateSql() for the same collection, checked at startup.

Pass the same shaping values to AddIngestion's ConfigureCollection that were passed to AddVectorStore.

IngestionSourceUnavailable = 6051

The configured folder is missing or unreadable, thrown before any document is processed.

Verify the path exists and the process has read access before calling RunAsync.

IngestionDocumentTooLarge = 6052

A document exceeded MaxDocumentBytes.

Raise MaxDocumentBytes, or exclude the oversized document from the source.

IngestionDocumentUnreadable = 6053

Opening the document raised IOException / UnauthorizedAccessException, or a non-seekable stream exceeded NonSeekableBufferLimitBytes.

Verify the file still exists and is readable; for a non-seekable source, raise NonSeekableBufferLimitBytes or supply a seekable stream.

IngestionDuplicateDocumentId = 6054

One DocumentId was yielded twice within the same run.

Make DocumentSourceItem.DocumentId (or the source's id derivation) unique per run.

IngestionSourceIdInvalid = 6055

An IngestionSource factory (Folder, Items) was given an invalid sourceId.

Supply a non-empty, stable sourceId — state rows are keyed on (collection, source_id, document_id).

ExtractorNotFound = 6101

No registered IDocumentExtractor claims the document's extension.

Register the matching satellite (AddPdfExtractor(), AddDocxExtractor()), or register a custom IDocumentExtractor for the extension.

ExtractionFailed = 6102

IDocumentExtractor.ExtractAsync threw something not already covered by DocumentEncrypted, DocumentMalformed, DocumentEncodingUndecodable or DocumentPageBudgetExceeded.

The document is recorded Failed and the run continues; one bad document fails one document, never a corpus.

DocumentEncrypted = 6103

PdfTextExtractor could not open an encrypted PDF with the configured Passwords.

Add the document's password to PdfExtractorOptions.Passwords, or exclude the document from the source.

DocumentMalformed = 6104

PdfTextExtractor or DocxTextExtractor could not parse the document's structure.

Re-export or repair the source document; PdfPig's UseLenientParsing (on by default) already tolerates the common cases.

DocumentHasNoTextLayer = 6105

Every page of a PDF has no text layer — a scanned document.

Run OCR upstream and re-ingest the result, or accept that the document is indexed as metadata only.

DocumentEncodingUndecodable = 6106

PlainTextExtractor found invalid UTF-8 with StrictUtf8 set.

Leave StrictUtf8 off (the default) to accept the Latin-1 fallback, or re-save the source file as valid UTF-8.

DocumentPageBudgetExceeded = 6107

A PDF's cumulative page-parse time passed PageBudget, checked at a page boundary.

Raise PdfExtractorOptions.PageBudget, or exclude the document.

ChunkExceedsTokenBudget = 6151

A chunker emitted a chunk over MaxTokens — an SP3 invariant violation, not a user-data problem.

This should never happen on a shipped chunker; if it follows a custom chunker or tokenizer change, check its pre-yield token verification.

ChunkContextTooLong = 6152

A chunk's heading-path breadcrumb still exceeds HeadingPathTokenBudget after left-truncation.

Raise HeadingPathTokenBudget, shorten the document's heading structure, or set Overflow to the mode that honours truncation instead of throwing.

ChunkTokenizerCeilingExceeded = 6153

The resolved IChunkTokenizer.MaxSequenceLength disagrees with ChunkModelProfile.MaxSequenceLength.

Use a tokenizer and a ChunkModelProfile for the same model — a mismatch means every number the budget resolves is a guess.

ChunkerProducedEmptyChunk = 6154

A chunker's pre-yield verification caught an empty chunk about to be emitted.

This should never happen on a shipped chunker; if it follows a custom chunker, check its emission logic.

MarkdownParseFailed = 6155

MarkdownExtractor (Markdig) failed to parse the document.

Validate the Markdown source, or extract it as plain text instead.

IngestionStateMissing = 6201

IngestionStateStore opened a database whose state tables do not exist.

Call AddIngestion(migrationVersion) so the migration creates the state tables before the first run.

IngestionHashAlgorithmMismatch = 6202

The state store's meta row records a hash algorithm different from the one the running code uses.

Delete the state rows and re-run to rebuild them under the current algorithm; this suite has no down-migrations.

IngestionStateSchemaUnsupported = 6203

The state store's meta row records a schema version the running code does not understand (forward-only; no down-migrations).

Upgrade to the package version that wrote the state, or delete the state rows and re-run.

IngestionStateCorrupt = 6204

A stored content hash is not the expected 16 bytes.

Delete the affected state row(s) and re-run so they are rebuilt cleanly.

IngestionCheckpointWriteFailed = 6205

ChunkWriter's state-write step failed — disk full, or SQLITE_BUSY past BusyTimeout.

The transaction rolls back and the run aborts, so an unwritten checkpoint cannot make the next run believe finished work is still owed; free disk space, raise BusyTimeout, or reduce write concurrency, then re-run.

IngestionEmbeddingFailed = 6206

SP3's own embed step (GenerateAsync) threw.

The runner halves the batch, retries the embed once, then suspends the run; inspect the inner exception, and for OnnxInsufficientMemory lower WriteBatchSize or the effective batch size.

IngestionWriteFailed = 6207

SP2's UpsertAsync or DeleteAsync threw.

Reported, not retried; inspect the inner EdgeVectorStoreException for the underlying store failure.

IngestionEmbeddingGeneratorMissing = 6208

No IEmbeddingGenerator<string, Embedding<float>> is resolvable, unkeyed or keyed on StoreName, at startup.

Call AddOnnxEmbeddings() or register another matching generator before AddIngestion.

ChatEnvironmentNotStarted = 7001

A Microsoft.ML.OnnxRuntimeGenAI type was reached before the startup task that starts it ran.

Call AddOnnxChat() and resolve IChatClient from the container rather than constructing EdgeChatClient directly.

ChatModelLoadFailed = 7002

new Model(...) or new Tokenizer(...) threw an OnnxRuntimeGenAIException, or the load did not finish inside LoadTimeout.

Carries the model directory and the inner message; re-provision the bundle if the files are damaged, or raise LoadTimeout if the device is simply slow to load.

ChatModelNotRegistered = 7003

A preset lookup (ChatPresets.ById) was asked for an id that does not match any of the shipped presets.

Check the spelling of the preset constant; only the shipped ChatPresets members exist in v1.

ChatUnsupportedRuntime = 7004

No ORT GenAI native for this RID or Android ABI. armeabi-v7a has none.

ChatInsufficientMemory = 7005

The memory budget refused even at MinContextTokens.

Carries the required, available and total byte counts and the largest context that would have fit; try a smaller preset, a lower MaxContextTokens, or the iOS increased-memory entitlements.

ChatDeviceTooSmall = 7006

Total device RAM is below the preset's floor, or the device reports IsLowRamDevice.

MinTotalMemoryBytes can be set to null to try anyway, at the risk of an OS kill.

ChatConfigurationInvalid = 7007

genai_config.json missing, unparseable or incoherent.

ChatModelShapeMismatch = 7008

The config disagrees with the preset's declared shape.

ChatExecutionProviderUnsupported = 7009

ConfigOverlayJson names an execution provider other than CPU on a mobile TFM, where GenAI has no CoreML and no NNAPI provider.

Remove the provider override on mobile targets; CPU is the only execution provider chat supports there in v1 (see ADR 0009).

ChatModelNotProvisioned = 7051

The model is absent on disk.

Carries the bundle's total byte count; call IChatModelProvisioner.Plan(), show the consent sheet it feeds, then ProvisionAsync().

ChatInsufficientDiskSpace = 7052

Free disk space is short of the bundle total plus a safety margin, checked before the first byte.

Free disk space, or choose the smaller preset.

ChatDownloadNotPermitted = 7053

ChatProvisioningOptions.IsTransferPermitted said no.

ChatTemplateUnsupported = 7101

minja could not parse the model's chat template, and RequireChatTemplate is set.

Set PromptFormatter to a formatter minja can parse, or a hand-written one.

ChatPromptTooLong = 7102

The prompt is still over budget after history reduction to the floor.

Carries both numbers; adjust MaxOutputTokens, ChatHistoryOptions, or RagOptions.MaxContextTokens.

ChatGuidanceUnavailable = 7103

ChatOptions.ResponseFormat is a ChatResponseFormatJson and the guidance policy is Disabled, or RequireNative/PreferNative and the positive-control probe did not come back Enforced.

The shipped mobile natives are built without USE_GUIDANCE; set EdgeGuidancePolicy.PreferNative to accept an unconstrained turn instead of a throw, or accept plain-text output.

ChatGenerationFailed = 7104

The native decode loop threw mid-decode.

Partial text already streamed stays streamed; the final update reports StopReason = Error before the exception surfaces. Inspect the inner exception and retry the turn.

ChatBusy = 7105

A second concurrent turn arrived while one was already running, the gate timed out, the queue is full, or turns are not being accepted.

The GenAI C API is not thread safe, so turns serialise onto one cached Generator; queue the caller's own retry rather than starting a second turn concurrently.

ChatThermalAbort = 7106

Device thermal state is at or above AbortAt before a turn starts.

The same condition reached mid-decode instead completes the stream with StopReason = Thermal; wait for the device to cool, or raise AbortAt/ThrottleAt if the app's own UX already warns the user.

ChatToolCallingUnsupported = 7107

ChatOptions.Tools is non-empty, or ToolMode requires a call — unsupported on a ~1B on-device model in v1 (see ADR 0012).

Remove Tools/ToolMode from the request, or perform tool calling above this client against a server-hosted model.

ChatOptionUnsupported = 7108

A message carries non-TextContent, or SearchOptions sets max_length directly.

max_length is refused whatever its type, because it is the memory cap the budget owns; use ChatOptions.MaxOutputTokens and the memory budget instead.

RagRetrieverMissing = 7201

UseRag() was added to the pipeline but no IEdgeRetriever is resolvable from the container.

Register one with AddVectorStoreRetriever/AddRetriever before resolving IChatClient.

RagRetrievalFailed = 7202

Retrieval threw and ContinueOnRetrievalFailure is false, or Top + Skip exceeded SQLITE_VEC_VEC0_K_MAX.

Fix the retriever's collection or query, or lower Top/Skip under the vec0 candidate ceiling; leave ContinueOnRetrievalFailure at its default to get an ungrounded answer instead of a throw.

RagCollectionNotSearchable = 7203

RequireHybridSearch is true and the collection does not implement IKeywordHybridSearchable<TRecord>.

Point the retriever at a collection that implements IKeywordHybridSearchable<TRecord>, or leave RequireHybridSearch at its default false to accept the vector-lane fallback.

RagContextBudgetTooSmall = 7204

MaxContextTokens cannot fit even one truncated source.

Raise RagOptions.MaxContextTokens, or lower MaxCharsPerSource so a single source fits inside the budget.