fix(search): un-gate the staged chunk recreate from the removed recreateIndex flag - #30364
Conversation
…ateIndex flag The staged chunk-index recreate (#30068) required jobData.recreateIndex == true, but SearchIndexAppConfigSanitizer (#28402) strips that removed option from every persisted config before jobData is built, so the guard could never pass: no staged generation, no alias promotion, no orphaned-chunk sweep — chunks silently fell back to the in-place rebuild while every per-entity index kept recreating. A job-driven run covering every vector-indexable type now stages the chunk recreate unconditionally (reindexes are always recreate-mode post-#28402); the jobless ops-CLI createIndexes path stays excluded via the jobData null-check. Also probe the read alias with the quiet boolean existsAlias instead of a throwing GET /_alias/{base}: on the pre-promotion physical-index layout the alias legitimately does not exist, and executeGenericRequest logged that expected 404 as an ERROR with a full stack trace once per process on every instance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ PR checks passedThe linked issue has a description and all required Shipping project fields set. Thanks! |
|
✅ Playwright Results — workflow succeededValidated commit ✅ 1024 passed · ❌ 0 failed · 🟡 2 flaky · ⏭️ 3 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 59m 55s ⏱️ Max setup 2m 53s · max shard execution 15m 59s · max shard-job elapsed before upload 20m 54s · reporting 7s 🌐 188.14 requests/attempt · 2.22 app boots/UI scenario · 20.10% common-shard skew Optimization targets still in progress:
🟡 2 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
…ateIndex flag (#30364) * fix(search): un-gate the staged chunk recreate from the removed recreateIndex flag The staged chunk-index recreate (#30068) required jobData.recreateIndex == true, but SearchIndexAppConfigSanitizer (#28402) strips that removed option from every persisted config before jobData is built, so the guard could never pass: no staged generation, no alias promotion, no orphaned-chunk sweep — chunks silently fell back to the in-place rebuild while every per-entity index kept recreating. A job-driven run covering every vector-indexable type now stages the chunk recreate unconditionally (reindexes are always recreate-mode post-#28402); the jobless ops-CLI createIndexes path stays excluded via the jobData null-check. Also probe the read alias with the quiet boolean existsAlias instead of a throwing GET /_alias/{base}: on the pre-promotion physical-index layout the alias legitimately does not exist, and executeGenericRequest logged that expected 404 as an ERROR with a full stack trace once per process on every instance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * greptile comments --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 1ae5a62)
|
Failed to cherry-pick changes to the 2.0 branch. |
Code Review ✅ ApprovedRestores generation-based chunk recreation for full app-driven reindexes by removing the obsolete recreateIndex flag guard and updating alias probing. No issues found. OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar | Powered by Gitar — free for open source |
|
Failed to cherry-pick changes to the 1.13 branch. |
|
Heads-up: this change makes a full reindex hard-depend on the embedding provider being reachable, and that has been breaking the nightly Java IT suites on What happensUn-gating the staged chunk recreate means every job-driven full recreate now reaches It surfaces as Why it affects more than CI
So on any deployment where a region resolves (anything on AWS) but Two configurations behave differently, worth being explicit about:
OSS is unaffected — Evidence it's this commit
Proposed fix#31131 (main) / #31132 (2.0): treat an unavailable provider as "do not stage" rather than "fail" — return The pre-flight's intent is kept — it still refuses to stage a generation it could never finish — it just no longer takes the entity reindex down with it. Genuine staging failures (indeterminate live-target probe, failed index create) still throw, and Separately, open-metadata/openmetadata-nightly#285 points the Java IT cluster at DJL in-process embeddings so CI stops depending on Bedrock at all. Since |
…reachable (#31132) #30364 un-gated the staged chunk recreate, so every job-driven full recreate now calls beginStagedChunkRecreate(), which opens with a pre-flight embed. The pre-flight rethrows, and that exception fails the whole SearchIndexApp run — so a reindex that needs no embeddings at all is now blocked by an optional AI provider being unreachable. That is not a narrow case. Collate ships semanticSearchEnabled=true by default while llmConfiguration.embeddings.provider defaults to bedrock, and BedrockEmbeddingClient's constructor never calls AWS — it validates the model id, dimension and region, then builds the SDK client. So on any deployment where a region resolves (anything on AWS) but bedrock:InvokeModel was never granted, the client constructs happily, initializeVectorSearchService reports success, and the first full reindex dies: User: arn:aws:sts::...:assumed-role/... is not authorized to perform: bedrock:InvokeModel on resource: .../amazon.titan-embed-text-v2:0 (Status Code: 403) surfacing as status='failed' within seconds with an empty failureContext. The misconfiguration is otherwise invisible: live indexing logs embedding errors and carries on, so the deployment looks healthy right up until someone reindexes. This is what has been failing the nightly Java IT suites on main and 2.0. Treat an unavailable provider as "do not stage" rather than "fail": return null, which the caller already handles as the partial-recreate outcome — existing chunks stay live and are swept by the next recreate that runs with a working provider. markEntityTypeReindexed already ignores marks from a run without staging, so this reuses a supported state rather than inventing one. Genuine staging failures — an indeterminate live-target probe, a failed index create — still throw, because those mean continuing could destroy live chunks.
…reachable (open-metadata#31131) open-metadata#30364 un-gated the staged chunk recreate, so every job-driven full recreate now calls beginStagedChunkRecreate(), which opens with a pre-flight embed. The pre-flight rethrows, and that exception fails the whole SearchIndexApp run — so a reindex that needs no embeddings at all is now blocked by an optional AI provider being unreachable. That is not a narrow case. Collate ships semanticSearchEnabled=true by default while llmConfiguration.embeddings.provider defaults to bedrock, and BedrockEmbeddingClient's constructor never calls AWS — it validates the model id, dimension and region, then builds the SDK client. So on any deployment where a region resolves (anything on AWS) but bedrock:InvokeModel was never granted, the client constructs happily, initializeVectorSearchService reports success, and the first full reindex dies: User: arn:aws:sts::...:assumed-role/... is not authorized to perform: bedrock:InvokeModel on resource: .../amazon.titan-embed-text-v2:0 (Status Code: 403) surfacing as status='failed' within seconds with an empty failureContext. The misconfiguration is otherwise invisible: live indexing logs embedding errors and carries on, so the deployment looks healthy right up until someone reindexes. This is what has been failing the nightly Java IT suites on main and 2.0. Treat an unavailable provider as "do not stage" rather than "fail": return null, which the caller already handles as the partial-recreate outcome — existing chunks stay live and are swept by the next recreate that runs with a working provider. markEntityTypeReindexed already ignores marks from a run without staging, so this reuses a supported state rather than inventing one. Genuine staging failures — an indeterminate live-target probe, a failed index create — still throw, because those mean continuing could destroy live chunks.



Fixes #30363
The staged, generation-based chunk-index recreate (#30068) never fired in any app-driven reindex: it gated on
Boolean.TRUE.equals(getJobData().getRecreateIndex()), butSearchIndexAppConfigSanitizer(#28402, "always recreate on reindex; drop the recreateIndex flag") strips that removed option from every persisted config beforeEventPublisherJobis built, so the flag is always null and the guard silently returned — before either the staging call or the "Partial recreate" log. Verified on a live deployment: a full Entities=All reindex with embeddings enabled promoted every per-entity*_rebuild_*index and re-embedded chunks in place, but created no_g<ts>generation, no alias, and logged none of the chunk-staging lines. Net effect: the orphaned-chunk sweep the feature exists for never runs, and the read name never migrates to the alias layout, soresolveLiveChunkTarget's alias probe hits an expected 404 thatexecuteGenericRequestlogs as an ERROR with a full stack trace once per process on every instance.Two changes:
RecreateWithEmbeddings: the staging decision is nowshouldStageChunkRecreate(jobData, entities)— job-driven and covering every vector-indexable type — with no reference to the removed flag (post-refactor(search): always recreate on reindex; drop the recreateIndex … #28402 every app reindex is a recreate, so job-driven implies recreate; the jobless ops-CLIcreateIndexespath stays excluded via the jobData null-check, and partial runs keep the existing "Partial recreate" log and never stage). Staging cost is unchanged from the original design: unchanged entities reuse their stored vectors across generations, so a full recreate does not re-embed the catalog.OpenSearchVectorService.resolveLiveChunkTarget: probe the read alias with the quiet booleanexistsAliasbefore fetching its target, instead of a throwingGET /_alias/{base}— on the pre-promotion physical-index layout the alias legitimately does not exist, and the generic-request path logged that expected 404 at ERROR. Resolution semantics are unchanged (alias target → legacy physical index → null on fresh install).Regression tests pin the trap:
shouldStageChunkRecreatemust return true for a jobData deserialized from a sanitizer-shaped config (recreateIndexabsent → null), false without jobData, false for partial coverage.Type of change: Bug fix
🤖 Generated with Claude Code
Greptile Summary
This PR restores staged chunk-index recreation for full application-driven reindexes. The main changes are:
recreateIndexgate with job and entity-coverage checks.Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
Reviews (4): Last reviewed commit: "Merge branch 'main' into fix/staged-chun..." | Re-trigger Greptile
Context used: