fix(dotAI): EmbeddingContentListener runs CREATE EXTENSION vector on archive/delete even when dotAI is disabled
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Problem Statement
When dotAI is not configured/disabled, the embeddings content listener still attempts to initialize the PostgreSQL vector extension on archive/unpublish/delete operations. On a standard PostgreSQL instance without pgvector, this throws:
org.postgresql.util.PSQLException: ERROR: extension "vector" is not available
Detail: Could not open extension control file ".../vector.control": No such file or directory.
Hint: The extension must first be installed on the system where PostgreSQL is running.
The connection is then marked broken (SQLSTATE 0A000). The operation itself (archive/unpublish/delete) still completes — only the embeddings cleanup fails — but it logs a stack trace intermittently and forces a pgvector requirement on customers who don't use AI at all.
Root cause (confirmed with @ivan.hoffmann):
EmbeddingsInitializer.init()subscribesEmbeddingContentListenerunconditionally at startup — no AI-enabled gate, and no toggle to disable just this listener.EmbeddingContentListener.deleteFromIndexes()'s only guard is a call togetConfigJson(host). ButgetConfigJson()wrapsgetAppConfig()inTry.of(...).getOrElse(new JSONObject()), so when dotAI is disabled theDotAIAppConfigDisabledExceptionis swallowed and converted to an empty{}.deleteFromIndexes()does not check for the empty config and proceeds to callEmbeddingsAPIImpl.deleteEmbedding()regardless.deleteEmbedding()triggers the lazyEmbeddingsFactory.implsingleton, whose constructor runsinitVectorExtension()→CREATE EXTENSION vector.- The publish/add path (
addToIndexesIfNeeded) gets the same empty config but iterates over zero indexes → harmless no-op. Only the delete path fires the error, which is why it appears intermittently (archive/unpublish/delete only).
Steps to Reproduce
- Use a standard PostgreSQL DB without the pgvector extension installed.
- Leave dotAI unconfigured (no API key/URLs in Settings → Apps → dotAI).
- Archive, unpublish, or delete any contentlet.
- Observed:
EmbeddingContentListener.onArchive → deleteFromIndexes → EmbeddingsAPIImpl.deleteEmbedding → EmbeddingsFactory.<init> → initVectorExtension → CREATE EXTENSION vectorthrowsPSQLException: extension "vector" is not available; the pooled connection is marked broken.
Expected vs. Actual
- Expected: With dotAI disabled, no embeddings/vector initialization runs. No pgvector requirement on the database.
- Actual: The delete path attempts
CREATE EXTENSION vectorand errors on standard Postgres.
Acceptance Criteria
- With dotAI disabled, archive/unpublish/delete does not attempt to initialize the vector extension or touch the embeddings layer.
- No
PSQLException: extension "vector" is not availableis logged when dotAI is disabled. - No pgvector extension is required for normal content operations when AI is not in use.
- Integration test covering archive/delete on a disabled-dotAI host.
Proposed Fix (per @ivan.hoffmann)
Either:
- Have
deleteFromIndexes()check for an empty config JSON and return early, or - Have
getConfigJson()return anOptionalinstead of swallowingDotAIAppConfigDisabledException, and have callers short-circuit when absent.
Affected Version
25.07.10 LTS (present since the listener was registered in #28770 / 24.06.21). Please confirm whether a fix should be backported to the 25.07.x LTS line.
Proposed Priority
Priority 2 - Important
External Links
- Freshdesk ticket: https://dotcms.freshdesk.com/a/tickets/37875
- Slack confirmation: dotAI engineering thread in #feat-dotai (@ivan.hoffmann confirmed root cause and that no existing issue covers this)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with EmbeddingContentListener.deleteFromIndexes(), getConfigJson(), and EmbeddingsAPIImpl.deleteEmbedding(); trace how EmbeddingsFactory initializes the vector extension when dotAI is disabled. Run the relevant content archive, unpublish, or delete integration tests, then add coverage for a disabled-dotAI host and verify these operations do not touch embeddings or log a missing-vector error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, postgresql
- Domain
- backend, databases, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100