fix: make the Query/Scan refusal on a vector index reachable - #319
Merged
Conversation
A vector index is not a row in the indexes catalog, so index_info_by_table_id reported it as missing and Query/Scan answered "The table does not have the specified index" for an index the table does have. The intended refusals were dead code. On the index-not-found path both handlers now re-resolve the name against the table's vector index metadata and refuse with the measured messages: Query with "Query operation not supported on this index type." (trailing period, measured 2026-08-20), Scan without one. A backfilling index gets Scan's backfilling wording while Query keeps the type refusal; an index CREATING before its backfill starts stays index-not-found, all as measured. Measured precedence is preserved: on Query the KeyConditionExpression and ConsistentRead checks fire before the refusal, on Scan the refusal fires first.
Dual-target pytest and a wire test covering the refusals, the index-not-found contrast case, the measured precedence against the KeyConditionExpression and ConsistentRead checks, and base-table/GSI controls.
yesyayen
marked this pull request as ready for review
August 27, 2026 16:40
yesyayen
requested review from
LeeroyHannigan,
amrith,
c33howard,
jcshepherd,
pdf-amzn and
robinnsc
as code owners
August 27, 2026 16:40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Query and Scan naming an existing vector index returned the index-not-found message, indistinguishable from a nonexistent index. The intended refusals existed in both handlers but were dead code: a vector index is not a row in the
indexescatalog, soindex_info_by_table_idfailed withIndexNotFoundand the error propagated before theIndexType::Vectorguard could run.Both handlers now re-resolve an unresolved index name against the table's vector index metadata (engine-level, so every backend inherits it; backends without vector support are unchanged) and refuse with the messages and precedence captured from Amazon DynamoDB.
Behavior: today vs Amazon DynamoDB
All Amazon DynamoDB messages below were captured directly from the service (2026-08-20), on a table with an ACTIVE vector index
vidxunless stated. Every case is400 ValidationExceptionexcept the two controls.QuerywithIndexName= vector indexThe table does not have the specified index: vidxQuery operation not supported on this index type.(trailing period)ScanwithIndexName= vector indexThe table does not have the specified index: vidxScan operation not supported on this index type(no period)Query/Scanwith a nonexistentIndexNameThe table does not have the specified index: nosuchindexQueryon vector index +ConsistentRead: trueConsistent reads are not supported on global secondary indexes(fires before the refusal, GSI wording even for a vector index)Scanon vector index +ConsistentRead: trueScan operation not supported on this index type(refusal fires first)Queryon vector index, noKeyConditionExpressionEither the KeyConditions or KeyConditionExpression parameter must be specified in the request.(fires before the refusal)Query/Scanon vector index in CREATING, before backfillQueryon vector index mid-backfillQuery operation not supported on this index type.Scanon vector index mid-backfillCannot read from backfilling global secondary index: vidxQuery/Scanon the base table or a GSI of the same tableWhy
Conformance gap found by comparing ExtendDB against Amazon DynamoDB. The wrong message actively misleads: it denies that an index exists when the request's actual problem is naming a vector index in an operation that can never serve it.
Closes # n/a
Testing done
Captured every expected message and ordering from Amazon DynamoDB first (including the lifecycle matrix, observed live through a backfill window), then validated dual-target. The branch was rebased onto current main after the vector-search backend PRs merged; all gates below were re-run at the rebased tip, not carried over.
tests/test_vector_index_query_scan.py(12 cases: both refusals whole-string, not-found contrast, four measured precedence orderings, base-table and GSI controls).tests/rust:query_and_scan_on_a_vector_index_are_refused(refusals, contrast case, precedence, control) andscan_during_backfill_gets_the_backfilling_wording, which holds the backfill window open via the batch-delay setting, waits untilCREATINGwithBackfilling: trueis observed, and pins both mid-backfill messages in the same window.Checklist
cargo test --workspace)cargo fmt --check)cargo clippy -- -W clippy::pedantic)Storagetrait, auth model, on-diskformat, or public CLI surface, an RFC has been accepted or is linked
below. Otherwise, an ADR captures the decision (link below).
ADR / RFC: n/a
By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache License 2.0 and I agree to the Developer Certificate of
Origin (DCO). See CONTRIBUTING.md for details.