Bug Report: dream template apply aborts on library extension instead of warning and continuing
Severity: High
Category: Error Handling
Platform: All (macOS, Linux, Windows/WSL2)
Confidence: Confirmed
Description
dream template apply <template-id> exits with code 1 and a misleading "Unknown service" error when the template includes a library extension that has not been installed yet. The _template_apply function uses cmd_enable "$svc" || warn "..." expecting a non-zero return code on failure, but cmd_enable internally calls error() which calls exit 1. An exit 1 cannot be caught by || — it terminates the entire shell process. Built-in extensions with compose.yaml.disabled are not affected; only library extensions (those in resources/dev/extensions-library/) trigger this path.
Affected File(s)
dream-server/dream-cli (lines 3027–3042 — _template_apply)
dream-server/dream-cli (line 48 — error() definition: error() { echo -e "${RED}✗${NC} $1"; exit 1; })
Root Cause
# _template_apply, lines 3040-3041
log " Enabling $svc..."
cmd_enable "$svc" || warn " Failed to enable $svc (continuing)"
When $svc is a library extension not yet installed (e.g., aider, gitea, chromadb), cmd_enable hits:
# cmd_enable — directory existence check
local ext_dir="$INSTALL_DIR/extensions/services/$service_id"
[[ ! -d "$ext_dir" ]] && ext_dir="$INSTALL_DIR/data/user-extensions/$service_id"
[[ -d "$ext_dir" ]] || error "Unknown service: $input" # ← calls exit 1
error() runs exit 1, which terminates the entire shell. The || warn in _template_apply only catches non-zero return codes — it cannot intercept exit 1.
Evidence
# Line 48 of dream-cli — exit 1 is unconditional
error() { echo -e "${RED}✗${NC} $1"; exit 1; }
# _template_apply calls cmd_enable and expects || to handle failure
cmd_enable "$svc" || warn " Failed to enable $svc (continuing)"
# BUT: if cmd_enable calls error(), exit 1 kills the whole process —
# || warn is never reached
Platform Analysis
Reproduction
- Fresh install or any system where library extensions are not yet installed
- Run:
dream template apply ai-coding-workspace
- Template services:
[aider, gitea, chromadb, n8n, openclaw]
aider is a library extension not in extensions/services/ or data/user-extensions/
cmd_enable "aider" → error "Unknown service: aider" → exit 1
- Expected: Warning printed,
aider skipped, n8n and openclaw (built-in) still enabled
- Actual: Shell exits with code 1,
n8n and openclaw never enabled, no success message
Impact
10 out of 11 built-in templates include at least one library extension (aider, gitea, chromadb, librechat, flowise, langflow, crewai, label-studio, paperless-ngx, piper-audio, sillytavern, open-interpreter, baserow). The only unaffected template is creative-studio (GPU-only, all built-in services). dream template apply is effectively broken for all standard templates when library extensions are not pre-installed.
Suggested Approach
Wrap the cmd_enable call in a subshell (cmd_enable "$svc") || warn "..." so that exit 1 inside cmd_enable terminates only the subshell, not the parent. Alternatively, pre-check for the extension directory existence before calling cmd_enable and emit a clear "not installable from CLI — use dashboard" message for library extensions.
Filed by automated shell auditor after full-sweep review of shell changes merged 2026-04-06 → 2026-04-11. Commit range inspected: upstream/main @ c0600ca.
Bug Report:
dream template applyaborts on library extension instead of warning and continuingSeverity: High
Category: Error Handling
Platform: All (macOS, Linux, Windows/WSL2)
Confidence: Confirmed
Description
dream template apply <template-id>exits with code 1 and a misleading "Unknown service" error when the template includes a library extension that has not been installed yet. The_template_applyfunction usescmd_enable "$svc" || warn "..."expecting a non-zero return code on failure, butcmd_enableinternally callserror()which callsexit 1. Anexit 1cannot be caught by||— it terminates the entire shell process. Built-in extensions withcompose.yaml.disabledare not affected; only library extensions (those inresources/dev/extensions-library/) trigger this path.Affected File(s)
dream-server/dream-cli(lines 3027–3042 —_template_apply)dream-server/dream-cli(line 48 —error()definition:error() { echo -e "${RED}✗${NC} $1"; exit 1; })Root Cause
When
$svcis a library extension not yet installed (e.g.,aider,gitea,chromadb),cmd_enablehits:error()runsexit 1, which terminates the entire shell. The|| warnin_template_applyonly catches non-zero return codes — it cannot interceptexit 1.Evidence
Platform Analysis
Reproduction
dream template apply ai-coding-workspace[aider, gitea, chromadb, n8n, openclaw]aideris a library extension not inextensions/services/ordata/user-extensions/cmd_enable "aider"→error "Unknown service: aider"→exit 1aiderskipped,n8nandopenclaw(built-in) still enabledn8nandopenclawnever enabled, no success messageImpact
10 out of 11 built-in templates include at least one library extension (
aider,gitea,chromadb,librechat,flowise,langflow,crewai,label-studio,paperless-ngx,piper-audio,sillytavern,open-interpreter,baserow). The only unaffected template iscreative-studio(GPU-only, all built-in services).dream template applyis effectively broken for all standard templates when library extensions are not pre-installed.Suggested Approach
Wrap the
cmd_enablecall in a subshell(cmd_enable "$svc") || warn "..."so thatexit 1insidecmd_enableterminates only the subshell, not the parent. Alternatively, pre-check for the extension directory existence before callingcmd_enableand emit a clear "not installable from CLI — use dashboard" message for library extensions.Filed by automated shell auditor after full-sweep review of shell changes merged 2026-04-06 → 2026-04-11. Commit range inspected: upstream/main @ c0600ca.