[GH-ISSUE #36] issue: Terminal system prompt is never injected for orchestrator connections (/system fetch omits X-User-Id) #15

Closed
opened 2026-10-18 21:13:23 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @Classic298 on GitHub (Jul 10, 2026).
Original GitHub issue: https://github.com/open-webui/terminals/issues/36

Terminal system prompt is never injected for orchestrator connections (/system fetch omits X-User-Id)

Summary

For Open Terminal connections of type orchestrator, the terminal system prompt is silently never injected into chats. The backend fetches the prompt at connection-save time via GET {base}/api/config and GET {base}/system, but sends no X-User-Id header (and no auth at all on the /api/config probe). The Terminals orchestrator's /p/{policy_id}/* proxy routes require X-User-Id (FastAPI required header), so the fetch fails with 422, get_terminal_system_prompt() swallows the error and returns None, and server['system_prompt'] is never set. Models receive no terminal system prompt — neither the container default nor a custom OPEN_TERMINAL_SYSTEM_PROMPT.

Direct (non-orchestrator) connections are unaffected.

Environment

  • Open WebUI: bug present on current main
  • Terminals orchestrator: 0.0.5-dev (ghcr.io/open-webui/terminals:latest), Docker backend
  • open-terminal image: ghcr.io/open-webui/open-terminal:latest

Reproduction

  1. Run the Terminals orchestrator with an API key (TERMINALS_API_KEY).
  2. Create a policy with a custom prompt:
    curl -X PUT http://localhost:3000/api/v1/policies/demo \
      -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
      -d '{"env": {"OPEN_TERMINAL_SYSTEM_PROMPT": "MARKER-12345"}}'
    
  3. In Open WebUI: Admin → Settings → Integrations → Open Terminal → add an orchestrator connection with URL http://<orchestrator>:3000, Policy ID demo, Bearer key, Save.
  4. Open a new chat with the terminal tools enabled and ask the model to quote its system prompt.

Expected: the system prompt contains MARKER-12345 (the prompt served by the policy container's /system endpoint).

Actual: no terminal system prompt is injected at all. The model only sees the tool descriptions.

Direct proof of the failing request (this is exactly what the backend sends):

curl -i http://localhost:3000/p/demo/api/config
# → 422 {"detail":[{"type":"missing","loc":["header","X-User-Id"], ...}]}

curl -s -H "Authorization: Bearer $KEY" -H "X-User-Id: probe" \
  http://localhost:3000/p/demo/system
# → {"prompt": "MARKER-12345"}   ← the prompt is there; the fetch just can't reach it

Root cause

backend/open_webui/utils/tools.py:

  • get_terminal_system_prompt() (~line 1056): the /api/config feature probe is sent with no headers, and the /system fetch only gets the bearer header passed in.
  • _fetch_system_prompt() inside set_terminal_servers() (~line 1135): builds headers from the bearer key only — never adds X-User-Id.

The orchestrator's /p/{policy_id}/{path} routes declare X-User-Id as a required header (terminals/routers/auth.py, verify_user_id), so both requests 422. All exceptions/non-200s are swallowed (return None), making the failure invisible.

Suggested fix

Either (or both):

  • Send an X-User-Id header (e.g. a reserved system identifier) on the /api/config and /system fetches for orchestrator connections, and pass auth headers to the /api/config probe.
  • Coordinate with the Terminals repo to exempt GET /p/{policy_id}/system and GET /p/{policy_id}/api/config from the X-User-Id requirement (same pattern as the existing /p/{policy_id}/openapi.json special case, which serves via a system container). Companion issue filed there.

Also worth logging the fetch failure at warning instead of debug — this failed silently for every orchestrator user.

Originally created by @Classic298 on GitHub (Jul 10, 2026). Original GitHub issue: https://github.com/open-webui/terminals/issues/36 # Terminal system prompt is never injected for orchestrator connections (`/system` fetch omits `X-User-Id`) ## Summary For Open Terminal connections of type **orchestrator**, the terminal system prompt is silently never injected into chats. The backend fetches the prompt at connection-save time via `GET {base}/api/config` and `GET {base}/system`, but sends **no `X-User-Id` header** (and no auth at all on the `/api/config` probe). The Terminals orchestrator's `/p/{policy_id}/*` proxy routes require `X-User-Id` (FastAPI required header), so the fetch fails with **422**, `get_terminal_system_prompt()` swallows the error and returns `None`, and `server['system_prompt']` is never set. Models receive no terminal system prompt — neither the container default nor a custom `OPEN_TERMINAL_SYSTEM_PROMPT`. Direct (non-orchestrator) connections are unaffected. ## Environment - Open WebUI: bug present on current `main` - Terminals orchestrator: 0.0.5-dev (`ghcr.io/open-webui/terminals:latest`), Docker backend - open-terminal image: `ghcr.io/open-webui/open-terminal:latest` ## Reproduction 1. Run the Terminals orchestrator with an API key (`TERMINALS_API_KEY`). 2. Create a policy with a custom prompt: ```bash curl -X PUT http://localhost:3000/api/v1/policies/demo \ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"env": {"OPEN_TERMINAL_SYSTEM_PROMPT": "MARKER-12345"}}' ``` 3. In Open WebUI: Admin → Settings → Integrations → Open Terminal → add an **orchestrator** connection with URL `http://<orchestrator>:3000`, Policy ID `demo`, Bearer key, Save. 4. Open a new chat with the terminal tools enabled and ask the model to quote its system prompt. **Expected:** the system prompt contains `MARKER-12345` (the prompt served by the policy container's `/system` endpoint). **Actual:** no terminal system prompt is injected at all. The model only sees the tool descriptions. Direct proof of the failing request (this is exactly what the backend sends): ```bash curl -i http://localhost:3000/p/demo/api/config # → 422 {"detail":[{"type":"missing","loc":["header","X-User-Id"], ...}]} curl -s -H "Authorization: Bearer $KEY" -H "X-User-Id: probe" \ http://localhost:3000/p/demo/system # → {"prompt": "MARKER-12345"} ← the prompt is there; the fetch just can't reach it ``` ## Root cause `backend/open_webui/utils/tools.py`: - `get_terminal_system_prompt()` (~line 1056): the `/api/config` feature probe is sent with **no headers**, and the `/system` fetch only gets the bearer header passed in. - `_fetch_system_prompt()` inside `set_terminal_servers()` (~line 1135): builds `headers` from the bearer key only — never adds `X-User-Id`. The orchestrator's `/p/{policy_id}/{path}` routes declare `X-User-Id` as a required header (`terminals/routers/auth.py`, `verify_user_id`), so both requests 422. All exceptions/non-200s are swallowed (`return None`), making the failure invisible. ## Suggested fix Either (or both): - Send an `X-User-Id` header (e.g. a reserved system identifier) on the `/api/config` and `/system` fetches for orchestrator connections, and pass auth headers to the `/api/config` probe. - Coordinate with the Terminals repo to exempt `GET /p/{policy_id}/system` and `GET /p/{policy_id}/api/config` from the `X-User-Id` requirement (same pattern as the existing `/p/{policy_id}/openapi.json` special case, which serves via a system container). Companion issue filed there. Also worth logging the fetch failure at `warning` instead of `debug` — this failed silently for every orchestrator user.
Author
Owner

@owui-terminator[bot] commented on GitHub (Jul 10, 2026):

🔍 Related Issues Found

I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions:

  1. 🟣 #29 issue: system prompt env var not respected
    This closed issue reports the same user-visible symptom: configuring OPEN_TERMINAL_SYSTEM_PROMPT but the system prompt not reaching models when terminal tools are enabled. It is likely the same underlying prompt-injection path failing, even though it doesn’t mention the orchestrator-specific header omission.
    by Classic298

💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead.

This comment was generated automatically. React with 👍 if helpful, 👎 if not.

<!-- gh-comment-id:4939354557 --> @owui-terminator[bot] commented on GitHub (Jul 10, 2026): <!-- terminator-bot:related-issues-reply --> 🔍 **Related Issues Found** I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions: 1. 🟣 [#29](https://github.com/open-webui/terminals/issues/29) **issue: system prompt env var not respected** *This closed issue reports the same user-visible symptom: configuring `OPEN_TERMINAL_SYSTEM_PROMPT` but the system prompt not reaching models when terminal tools are enabled. It is likely the same underlying prompt-injection path failing, even though it doesn’t mention the orchestrator-specific header omission.* *by Classic298* --- 💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead. *This comment was generated automatically.* React with 👍 if helpful, 👎 if not.
Author
Owner

@Classic298 commented on GitHub (Jul 20, 2026):

fixed with open webui 0.10.3 or newer

<!-- gh-comment-id:5025291793 --> @Classic298 commented on GitHub (Jul 20, 2026): fixed with open webui 0.10.3 or newer
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
open-webui/terminals#15
No description provided.