Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .claude/skills/dify-docs-env-vars/ignored-vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ Meaningful only on the hosted Dify Cloud deployment; self-hosted users cannot us
| `TIDB_ON_QDRANT_GRPC_PORT` | Hybrid TiDB-Qdrant Cloud-only backend. | PR #721, commit 9248032 |
| `CREATE_TIDB_SERVICE_JOB_ENABLED` | Cloud-side TiDB pre-provisioning job. | PR #721, commit 9248032 |
| `AMPLITUDE_API_KEY` | Cloud product analytics integration. | PR #721, commit 9248032 |
| `COOKIEYES_SITE_KEY` | CookieYes consent-banner key for Dify Cloud analytics. The frontend boundary requires `EDITION=CLOUD` plus the Cloud console host (`web/app/components/base/analytics-consent/request-boundary.ts`); dify PR #39408 explicitly excludes self-hosted deployments. Companion to `AMPLITUDE_API_KEY`. | dify #39408, 1.16.1 sync audit 2026-07-23 |
| `ENABLE_TRIAL_APP` | Cloud trial-app runs on Explore. The server gate (`api/services/recommended_app_service.py`) requires the derived `DEPLOYMENT_EDITION` property to be CLOUD—i.e. the `EDITION` env var set to `CLOUD`—so the flag is inert on self-host: `can_trial` is always false and the `/trial-apps/*` endpoints 403. | dify #39562, 1.16.1 sync audit 2026-07-27 |
| `ENABLE_EXPLORE_BANNER` | Marketing banner carousel on the Explore page. Banner content comes from the `exporle_banners` DB table (sic—the table name is misspelled upstream, `api/models/model.py`), which has no CE management UI or seed data—enabling the flag on self-host renders nothing. | dify #39543, 1.16.1 sync audit 2026-07-27 |

## Experimental / internal

Expand All @@ -52,6 +55,21 @@ Feature flags for unfinished or staff-only features. Not yet meant for self-host
| Variable | Reason | Source |
|---|---|---|
| `EXPERIMENTAL_ENABLE_VINEXT` | Switches the web container to an experimental Vite-based server (`web/docker/entrypoint.sh`). Not a supported user-facing knob. | 1.14 sync audit, 2026-04-22 |
| `KNOWLEDGE_FS_ENABLED` | Feature flag for the unreleased New Knowledge (KnowledgeFS) Console bridge. Default false; every proxy route 404s and the frontend hides the UI while off (`api/controllers/console/knowledge_fs_proxy.py`). Document the group and drop these five entries when the feature ships enabled. | dify #39158/#39314, 1.16.1 sync audit 2026-07-23 |
| `KNOWLEDGE_FS_BASE_URL` | Connection setting for the flag-off KnowledgeFS bridge; inert unless `KNOWLEDGE_FS_ENABLED=true`. | dify #39158/#39314, 1.16.1 sync audit 2026-07-23 |
| `KNOWLEDGE_FS_JWT_SECRET` | Service-JWT signing secret for the flag-off KnowledgeFS bridge; inert unless enabled. | dify #39158/#39314, 1.16.1 sync audit 2026-07-23 |
| `KNOWLEDGE_FS_TIMEOUT_SECONDS` | Request timeout for the flag-off KnowledgeFS bridge; inert unless enabled. | dify #39158/#39314, 1.16.1 sync audit 2026-07-23 |
| `KNOWLEDGE_FS_SSE_READ_TIMEOUT_SECONDS` | SSE idle-read timeout for the flag-off KnowledgeFS bridge; inert unless enabled. | dify #39158/#39314, 1.16.1 sync audit 2026-07-23 |
| `ENABLE_STEP_BY_STEP_TOUR` | Staged-rollout onboarding tour (home/studio/knowledge/integration guides). Flag-off, and eligibility additionally requires `STEP_BY_STEP_TOUR_ROLLOUT_STARTED_AT`, which is Pydantic-only (`api/services/step_by_step_tour_service.py` `is_eligible`)—the tour cannot be turned on from the docker env alone. Revisit when it ships enabled. | dify #38785/#39399, 1.16.1 sync audit 2026-07-27 |

## Enterprise-only

Switches for the Dify Enterprise control plane. Inert at their defaults on Community Edition; enabling them without the Enterprise services makes the deployment call APIs that don't exist. Enterprise deployments configure them through the EE Helm chart, not this file.

| Variable | Reason | Source |
|---|---|---|
| `ENTERPRISE_ENABLED` | Master switch for EE integrations (branding, SSO, license, webapp auth). At `false` it is fully inert on CE. Setting `true` makes `get_system_features` call `EnterpriseService.get_info()` against `ENTERPRISE_API_URL`, which has no CE backend—based on the code, the console then fails to load. | dify #39543, 1.16.1 sync audit 2026-07-27 |
| `RBAC_ENABLED` | Routes permission checks to the EE inner RBAC API (`rbac_permission_required` in `api/controllers/common/wraps.py` is an explicit no-op when false). On CE there is no RBAC service to answer the checks. | dify #39543, 1.16.1 sync audit 2026-07-27 |

## Verifier false positives

Expand All @@ -61,3 +79,4 @@ The variable is documented in `environments.mdx`, but the verifier misreports it
|---|---|---|
| `ALIYUN_CLOUDBOX_ID` | Commented-out `#ALIYUN_CLOUDBOX_ID=your-cloudbox-id` in `docker/.env.example`; backend field exists in `api/configs/middleware/storage/aliyun_oss_storage_config.py`. | 1.14 sync audit, 2026-04-22 |
| `DIFY_AGENT_SERVER_SECRET_KEY` | Documented with a descriptive default; `.env.example` pre-fills a development key that the docs must not reproduce (no real or example secret values in docs). | feat/agent-v2 audit, 2026-07-09 |
| `DIFY_AGENT_API_TOKEN` | Documented with a descriptive default; `.env.example` pre-fills a development bearer token that the docs describe instead of reproduce (same rule as `DIFY_AGENT_SERVER_SECRET_KEY`). | dify #39544/#39622, 1.16.1 sync audit 2026-07-27 |
10 changes: 9 additions & 1 deletion en/api-reference/openapi_service.json
Original file line number Diff line number Diff line change
Expand Up @@ -1963,10 +1963,18 @@
}
},
"400": {
"description": "- `app_unavailable` : The app is unavailable or misconfigured.\n- `speech_to_text_disabled` : Speech-to-text is disabled for this app.\n- `provider_not_support_speech_to_text` : The model provider does not support speech-to-text.\n- `provider_not_initialize` : No valid model provider credentials are configured.\n- `provider_quota_exceeded` : The model provider quota is exhausted.\n- `model_currently_not_support` : The current model does not support this operation.\n- `completion_request_error` : The speech recognition request failed.",
"description": "- `no_audio_uploaded` : No audio file was provided in the `file` field.\n- `app_unavailable` : The app is unavailable or misconfigured.\n- `speech_to_text_disabled` : Speech-to-text is disabled for this app.\n- `provider_not_support_speech_to_text` : The model provider does not support speech-to-text.\n- `provider_not_initialize` : No valid model provider credentials are configured.\n- `provider_quota_exceeded` : The model provider quota is exhausted.\n- `model_currently_not_support` : The current model does not support this operation.\n- `completion_request_error` : The speech recognition request failed.",
"content": {
"application/json": {
"examples": {
"no_audio_uploaded": {
"summary": "no_audio_uploaded",
"value": {
"status": 400,
"code": "no_audio_uploaded",
"message": "Please upload your audio."
}
},
"app_unavailable": {
"summary": "app_unavailable",
"value": {
Expand Down
22 changes: 21 additions & 1 deletion en/develop-plugin/dev-guides-and-walkthroughs/tool-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ extra:
- **`identity`**: Basic information about the tool, including name, author, label, and description.
- **`parameters`**: The parameter list.
- **`name`** (required): Parameter name; must be unique among the tool's parameters.
- **`type`** (required): Parameter type. One of `string`, `number`, `boolean`, `select`, or `secret-input`, rendered as a string, number, boolean, dropdown, or encrypted input box. Use `secret-input` for sensitive information.
- **`type`** (required): Parameter type. One of `string`, `number`, `boolean`, `select`, `dynamic-select`, or `secret-input`, rendered as a string, number, boolean, dropdown, dynamic dropdown, or encrypted input box. `dynamic-select` options are fetched from the plugin at configuration time; use `secret-input` for sensitive information.
- **`label`** (required): Parameter label, shown in the frontend.
- **`form`** (required): Form type, either `llm` or `form`.
- In Agent applications, `llm` means the LLM infers the parameter itself, while `form` means the parameter can be preset before using the tool.
Expand All @@ -243,6 +243,26 @@ extra:
- **`options`** (optional): Parameter options.
- In `llm` mode, Dify passes all options to the LLM, which can infer based on them.
- In `form` mode, the frontend displays the options when `type` is `select`.
- **`multiple`** (optional): For `select` and `dynamic-select` parameters, set `true` to let users pick more than one option. The value is passed as a list of option values, and `default`, if set, must then be a list.

```yaml
- name: formats
type: select
multiple: true
form: form
label:
en_US: Formats
options:
- label:
en_US: Markdown
value: markdown
- label:
en_US: Links
value: links
default:
- markdown
```

- **`default`** (optional): Default value.
- **`min`** (optional): Minimum value; applies when the parameter type is `number`.
- **`max`** (optional): Maximum value; applies when the parameter type is `number`.
Expand Down
22 changes: 22 additions & 0 deletions en/self-host/deploy/configuration/environments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ If you use your own reverse proxy, forward `Upgrade` and `Connection` headers on
| `FLASK_DEBUG` | `false` | Standard Flask debug mode flag. Not actively used by Dify; `DEBUG` is the primary control. |
| `ENABLE_REQUEST_LOGGING` | `false` | Logs a compact access line (`METHOD PATH STATUS DURATION TRACE_ID`) for every HTTP request. When `LOG_LEVEL` is also set to `DEBUG`, additionally logs full request and response bodies as JSON. |
| `DEPLOY_ENV` | `PRODUCTION` | Tags monitoring data in Sentry and OpenTelemetry so you can filter errors and traces by environment. Also sent as the `X-Env` response header. Does not change application behavior. |
| `EDITION` | `SELF_HOSTED` | Deployment identity, exposed to the console as `deployment_edition`. Keep the default: `CLOUD` is the mode Dify's hosted service runs in—it skips the initial admin-setup wizard and switches on billing and hosted-model behavior that talks to Dify-internal services, so a deployment set to `CLOUD` cannot complete setup. |
| `MIGRATION_ENABLED` | `true` | When `true`, runs database schema migrations (`flask upgrade-db`) automatically on container startup. Docker only. Set to `false` if you run migrations separately. For source code launches, run `flask db upgrade` manually. |
| `CHECK_UPDATE_URL` | `https://updates.dify.ai` | The console checks this URL for newer Dify versions. Set to empty to disable—useful for air-gapped environments or to prevent external HTTP calls. |
| `OPENAI_API_BASE` | `https://api.openai.com/v1` | Legacy variable. Not actively used by Dify's own code. May be picked up by the OpenAI Python SDK if present in the environment. |
Expand Down Expand Up @@ -1153,6 +1154,19 @@ For more details, see the [SendGrid documentation](https://www.twilio.com/docs/s
|---|---|---|
| `ENABLE_LEARN_APP` | `true` | Shows the Learn Dify section: tutorial templates on the Explore page, the getting-started panel when Studio has no apps, and its show/hide toggle in the help menu.<br/>Set to `false` to hide all three. |

#### Authentication and Accounts

By default, sign-in is email + password, and new accounts come from workspace invitations or the initial setup wizard. The toggles below relax or tighten that.

| Variable | Default | Description |
|---|---|---|
| `ENABLE_EMAIL_PASSWORD_LOGIN` | `true` | Sign in to the console with email and password. When disabled, the password form disappears from the sign-in page and the password login, password reset, and self-serve signup endpoints all return 403. Keep at least one sign-in method enabled—if every method is off, the sign-in page shows "Authentication method not configured" and no one can log in until you change the setting back. |
| `ENABLE_EMAIL_CODE_LOGIN` | `false` | Sign in with a one-time 6-digit code sent by email instead of a password. Requires mail delivery to be configured (see [Mail Configuration](#mail-configuration))—without it, codes are never delivered. With `ALLOW_REGISTER=true`, entering a code for an unknown email also creates the account, so this doubles as a self-serve signup path. |
| `ENABLE_SOCIAL_OAUTH_LOGIN` | `false` | Shows GitHub and Google sign-in buttons on the console sign-in page. The buttons only work if the matching GitHub or Google OAuth app credentials are also configured on the API service; with the flag on but no credentials, sign-in attempts fail. First-time OAuth sign-ins create an account only when `ALLOW_REGISTER=true`. |
| `ALLOW_REGISTER` | `false` | Lets people create their own accounts: shows the sign-up link on the sign-in page (with password login enabled) and allows first-time email-code or OAuth sign-ins to create accounts. Leave `false` for an invite-only deployment—workspace invitations and the initial setup wizard always work regardless. |
| `ALLOW_CREATE_WORKSPACE` | `false` | Automatically creates a workspace for an account that doesn't belong to one—during self-serve registration and at email-code or OAuth sign-in. When `false`, such accounts must wait for a workspace invitation. The admin workspace created by the setup wizard is unaffected. |
| `ENABLE_CHANGE_EMAIL` | `true` | Lets users change their account's email address from the account settings page. The flow confirms the change with emailed verification codes, so it requires mail delivery to be configured. Set to `false` to lock account emails, e.g. when they must match an external directory. |

#### LLMOps Trace Delivery

Traces of app runs are delivered to the configured LLMOps provider (Langfuse, LangSmith, Arize/Phoenix, and so on) by a background task. These variables govern its retries on transient failures.
Expand Down Expand Up @@ -1347,6 +1361,14 @@ Generate one with:
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
```

### DIFY_AGENT_API_TOKEN

Default: (development token pre-filled in `.env.example`; must be replaced for production)

Bearer token the Dify API presents when calling the agent backend's run API. Compose passes the same value to both services, so setting it once keeps them in agreement.

A publicly known development token ships as the default, so the stack starts out of the box—but anyone who can reach the agent backend and knows the token can start runs. Replace it with your own random value before production use.

### NEXT_PUBLIC_ENABLE_AGENT_V2

Default: `true`
Expand Down
2 changes: 1 addition & 1 deletion en/self-host/deploy/quick-start/docker-compose.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Make sure your machine meets the following minimum system requirements.
The following containers will be started:

- 7 core services: `api`, `api_websocket`, `worker`, `worker_beat`, `web`, `plugin_daemon`, `agent_backend`
- 7 dependent components: `weaviate`, `db_postgres`, `redis`, `nginx`, `ssrf_proxy`, `sandbox`, `local_sandbox`
- 8 dependent components: `weaviate`, `db_postgres`, `redis`, `nginx`, `ssrf_proxy`, `agent_ssrf_proxy`, `sandbox`, `local_sandbox`
- 1 one-time task: `init_permissions`, which sets storage file permissions and exits when done

4. Verify that all containers are running successfully:
Expand Down
2 changes: 1 addition & 1 deletion en/self-host/use-dify/build/new-agent/build.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ If your deployment requires strong isolation or strict security or compliance co
<Tip>
The new Agent is in beta. It's on by default on Docker Compose, with its runtime bundled in.

For production, replace [`DIFY_AGENT_SERVER_SECRET_KEY`](/en/self-host/deploy/configuration/environments#dify_agent_server_secret_key) with your own random value.
For production, replace [`DIFY_AGENT_SERVER_SECRET_KEY`](/en/self-host/deploy/configuration/environments#dify_agent_server_secret_key) and [`DIFY_AGENT_API_TOKEN`](/en/self-host/deploy/configuration/environments#dify_agent_api_token) with your own random values.
</Tip>

## Create an Agent
Expand Down
2 changes: 1 addition & 1 deletion en/self-host/use-dify/build/new-agent/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ If your deployment requires strong isolation or strict security or compliance co
<Tip>
The new Agent is in beta. It's on by default on Docker Compose, with its runtime bundled in.

For production, replace [`DIFY_AGENT_SERVER_SECRET_KEY`](/en/self-host/deploy/configuration/environments#dify_agent_server_secret_key) with your own random value.
For production, replace [`DIFY_AGENT_SERVER_SECRET_KEY`](/en/self-host/deploy/configuration/environments#dify_agent_server_secret_key) and [`DIFY_AGENT_API_TOKEN`](/en/self-host/deploy/configuration/environments#dify_agent_api_token) with your own random values.
</Tip>

An *Agent* is an AI worker you set up once and then put to work. It's a different kind of agent than the [classic Agent app](/en/self-host/use-dify/build/agent):
Expand Down
8 changes: 4 additions & 4 deletions en/self-host/use-dify/nodes/agent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: Run an agent as a step in your workflow, reasoning and using tools
<Tip>
The new Agent node is in beta. It's on by default on Docker Compose, with its runtime bundled in.

For production, replace [`DIFY_AGENT_SERVER_SECRET_KEY`](/en/self-host/deploy/configuration/environments#dify_agent_server_secret_key) with your own random value.
For production, replace [`DIFY_AGENT_SERVER_SECRET_KEY`](/en/self-host/deploy/configuration/environments#dify_agent_server_secret_key) and [`DIFY_AGENT_API_TOKEN`](/en/self-host/deploy/configuration/environments#dify_agent_api_token) with your own random values.
</Tip>

<Tabs>
Expand Down Expand Up @@ -137,9 +137,9 @@ description: Run an agent as a step in your workflow, reasoning and using tools

You pick the agent and tell it what to do; it works through the task on its own and hands the results back to the rest of the flow.

<Note>
In a Chatflow, the agent doesn't keep conversation-scoped memory: it handles each message from scratch.
</Note>
<Info>
The new Agent node is available in Workflow apps only.
</Info>

## Choose an Agent

Expand Down
10 changes: 9 additions & 1 deletion ja/api-reference/openapi_service.json
Original file line number Diff line number Diff line change
Expand Up @@ -1963,10 +1963,18 @@
}
},
"400": {
"description": "- `app_unavailable` : アプリケーションが利用できないか、設定が正しくありません。\n- `speech_to_text_disabled` : このアプリでは音声からテキストへの変換が無効になっています。\n- `provider_not_support_speech_to_text` : モデルプロバイダーが音声認識をサポートしていません。\n- `provider_not_initialize` : 有効なモデルプロバイダーの認証情報が見つかりません。\n- `provider_quota_exceeded` : モデルプロバイダーのクォータが使い切られました。\n- `model_currently_not_support` : 現在のモデルはこの操作をサポートしていません。\n- `completion_request_error` : 音声認識リクエストに失敗しました。",
"description": "- `no_audio_uploaded` : 音声ファイルがアップロードされていません(`file` フィールドがありません)。\n- `app_unavailable` : アプリケーションが利用できないか、設定が正しくありません。\n- `speech_to_text_disabled` : このアプリでは音声からテキストへの変換が無効になっています。\n- `provider_not_support_speech_to_text` : モデルプロバイダーが音声認識をサポートしていません。\n- `provider_not_initialize` : 有効なモデルプロバイダーの認証情報が見つかりません。\n- `provider_quota_exceeded` : モデルプロバイダーのクォータが使い切られました。\n- `model_currently_not_support` : 現在のモデルはこの操作をサポートしていません。\n- `completion_request_error` : 音声認識リクエストに失敗しました。",
"content": {
"application/json": {
"examples": {
"no_audio_uploaded": {
"summary": "no_audio_uploaded",
"value": {
"status": 400,
"code": "no_audio_uploaded",
"message": "Please upload your audio."
}
},
"app_unavailable": {
"summary": "app_unavailable",
"value": {
Expand Down
Loading
Loading