vxcontrol/pentagi · error · FatalError
internal engine: no link-discovery engine is available
Error message
internal engine: no link-discovery engine is available
What it means
`discoverURLs` iterates over the internal engine's configured link-discovery searchers and calls the first one whose `IsAvailable()` is true. If every entry is nil or unavailable (no search backend configured/keys missing), it returns this Fatal error (backend/pkg/tools/searchers/internal.go:223) — the internal engine cannot even begin because it depends entirely on a link-discovery engine for candidate URLs.
Source
Thrown at backend/pkg/tools/searchers/internal.go:223
// discoverURLs asks the first available link searcher for candidate URLs and extracts
// them from its markdown output. A discovery error is propagated as-is (already typed).
func (e *internalEngine) discoverURLs(ctx context.Context, req Request) ([]string, string, error) {
linkReq := Request{Query: req.Query, MaxResults: internalLinkDiscoveryLimit}
for _, l := range e.links {
if l == nil || !l.IsAvailable() {
continue
}
out, err := l.Handle(ctx, linkReq)
if err != nil {
// Propagate the typed error from the link engine; the orchestrator decides
// retry-vs-fallback for the internal engine as a whole.
return nil, "", err
}
return dedupeURLs(urlPattern.FindAllString(out, -1)), out, nil
}
return nil, "", Fatal(fmt.Errorf("internal engine: no link-discovery engine is available"))
}
func (e *internalEngine) buildPrompt(query string, blocks []string) string {
var sb strings.Builder
sb.WriteString("<instructions>\n")
sb.WriteString("TASK: Answer the user query using ONLY the web sources below.\n\n")
sb.WriteString(fmt.Sprintf("USER QUERY: %q\n\n", query))
sb.WriteString("REQUIREMENTS:\n")
sb.WriteString("1. Give a direct, comprehensive answer to the user query.\n")
sb.WriteString("2. Preserve critical facts, numbers, commands, code snippets, and technical details.\n")
sb.WriteString("3. Remove any non-essential details that are not relevant to the user query.\n")
sb.WriteString("4. Cite sources as [Source #] where # is the source id.\n")
sb.WriteString("5. If the sources do not answer the query, say so explicitly.\n")
sb.WriteString("6. Use `###` headers to separate paragraphs.\n")
sb.WriteString("</instructions>\n\n")
for _, b := range blocks {
sb.WriteString(b)
sb.WriteString("\n\n")View on GitHub (pinned to ea665308ba)
Solutions
- Configure at least one link-capable search engine: set its API key/env vars in .env (and docker-compose.yml) and restart
- Check Settings UI → search engines and enable one whose Engine() can serve as a link source
- Verify the engine is placed in the internal engine's link list in buildSearchEngines (internal.go constructor wiring)
- Confirm env vars are actually passed into the backend container (docker compose config) — a missing env var makes IsAvailable() false
Example fix
// before: .env with no search engine # no search keys // after SEARXNG_URL=http://searxng:8080 # or TAVILY_API_KEY=tvly-...
Defensive patterns
Strategy: validation
Validate before calling
// startup check: at least one link engine available
avail := false
for _, l := range linkEngines {
if l != nil && l.IsAvailable() { avail = true; break }
}
if !avail {
return fmt.Errorf("no link-discovery search engine configured; set e.g. SEARXNG_URL or TAVILY_API_KEY")
} Try / catch
_, err := engine.Handle(ctx, req)
if err != nil && searchers.IsFatal(err) && strings.Contains(err.Error(), "no link-discovery engine") {
// configuration problem: do not retry, fix env/config
} Prevention
- Set at least one search-engine API key/env var in .env and docker-compose.yml before enabling the internal engine
- Verify env vars reach the backend container (docker compose config)
- Enable search engines in the Settings UI and confirm IsAvailable() passes at startup
- Keep engine wiring in buildSearchEngines consistent with enabled config
When it happens
Trigger: `Handle` on the internal engine runs while no link searcher is configured, or all configured ones return `IsAvailable() == false` because their API keys/env vars (e.g. DUCKDUCKGO_*, SEARCHXNG_URL, TAVILY_API_KEY) are unset.
Common situations: Fresh deployment with no search-engine keys in .env; search engine disabled in Settings UI after enabling the internal engine; typo'd env var so availability check fails; `links` slice built empty in buildSearchEngines because all constructors reported not-configured.
Related errors
- failed to get searcher handler: %w
- token validation disabled with default salt
- Token.CreationDisabled
- Internal
- there are temporarily offline for maintenance. please try ag
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/2f5b24df0a26b703.
Report an issue: GitHub.