Skip to content

apply_template silently skips built-in (non-catalog) extensions — all 11 templates affected #320

@yasinBursali

Description

@yasinBursali

Bug Report: apply_template silently skips built-in extensions — all 11 templates affected

Severity: High
Category: Infra
Platform: All
Confidence: Confirmed

Description

POST /api/templates/{id}/apply silently skips any built-in extension that is not currently healthy. The response reports results[svc_id] = "skipped: Extension not installed: X" and restart_required: false with enabled_count: 0, which looks like a successful apply to the frontend even though nothing was enabled.

Affected File(s)

  • dream-server/extensions/services/dashboard-api/routers/templates.pyapply_template(), _BASE_COMPOSE_SERVICES
  • dream-server/extensions/services/dashboard-api/routers/extensions.py_activate_service()

Root Cause

_activate_service(service_id) resolves ext_dir = USER_EXTENSIONS_DIR / service_id. Built-in extensions (n8n, litellm, langfuse, tts, whisper, openclaw, perplexica, searxng, privacy-shield, token-spy, comfyui) live in EXTENSIONS_DIR, not USER_EXTENSIONS_DIR. The check ext_dir.is_dir() returns False, raising HTTPException(404, "Extension not installed: n8n").

apply_template wraps the call in try/except HTTPException and records the result as "skipped: Extension not installed: n8n" — no user-visible error.

The comment in templates.py says _activate_service checks both user-installed and built-in extension dirs, but this is incorrect. The code only checks USER_EXTENSIONS_DIR.

_BASE_COMPOSE_SERVICES = frozenset({"llama-server", "open-webui", "dashboard", "dashboard-api"}) — correctly excludes always-running services but does not include other built-in extensions (n8n, litellm, etc.).

Evidence

# extensions.py:977
def _activate_service(service_id: str) -> dict:
    ext_dir = (USER_EXTENSIONS_DIR / service_id).resolve()   # ← only USER_EXTENSIONS_DIR
    if not ext_dir.is_dir():
        raise HTTPException(status_code=404, detail=f"Extension not installed: {service_id}")

Compare with _is_dep_enabled() at line 936, which correctly checks both dirs:

if (EXTENSIONS_DIR / dep / "compose.yaml").exists():   # ← correctly checks EXTENSIONS_DIR
    return True
if (USER_EXTENSIONS_DIR / dep / "compose.yaml").exists():
    return True

Services silently skipped per template

Template Built-in services silently skipped if not healthy
ai-coding-workspace n8n, openclaw
chat-playground tts, whisper
creative-studio comfyui, tts, whisper
developer-homelab n8n, token-spy
llm-platform litellm, langfuse, token-spy, n8n
ml-data-workshop litellm, langfuse, n8n
multi-agent-laboratory openclaw, langfuse, n8n
no-code-ai-builder n8n
personal-knowledge-base perplexica, searxng, whisper
private-research-hub searxng, perplexica, privacy-shield
voice-assistant whisper, tts, n8n

All 11 templates are affected.

Platform Analysis

All platforms. The template system is a dashboard-api feature with no platform-specific branching.

Reproduction

  1. Have a DreamServer install where n8n is not running (or disable it: rename extensions/services/n8n/compose.yamlcompose.yaml.disabled)
  2. POST /api/templates/no-code-ai-builder/apply with valid API key
  3. Response shows "n8n": "skipped: Extension not installed: n8n" and enabled_count: 0
  4. UI shows "Template applied" but n8n is not running

Impact

The template system's primary purpose — setting up groups of services with one click — is broken for built-in services that are not currently running. All 11 templates fail silently for a majority of their listed services on systems where those services aren't already healthy.

Suggested Approach

Add a built-in extension activation path in apply_template that checks EXTENSIONS_DIR / svc_id / "compose.yaml.disabled" and renames it to compose.yaml (same mechanism _activate_service uses for USER_EXTENSIONS_DIR). Mirror the pattern from _is_dep_enabled() which already correctly checks both directories.


Filed by automated infra auditor after full-sweep of changes merged 2026-04-06 → 2026-04-11 on upstream/main @ c0600ca.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions