[Feature] Marketplace should handle plugin ↔ Dify version compatibility (`minimum_dify_version` is currently a no-op)
- Dominant language
- TypeScript
- Stars
- 156k
- Forks
- 24.6k
- Avg merge
- 20h 50m
- Merged PRs (30d)
- 586
Description
# [Feature] Marketplace should handle plugin ↔ Dify version compatibility (`minimum_dify_version` is currently a no-op)
> Target repo: `langgenius/dify` (behavior also spans the hosted Marketplace API and `langgenius/dify-plugin-daemon`)
## Self Checks
- [x] I have searched for existing issues, including closed ones.
- [x] I confirm that I am using English to submit this report.
- [x] Please do not modify this template :) and fill in all the required fields.
## 1. Is this request related to a challenge you're experiencing?
Yes. When installing a plugin (from Marketplace, GitHub, or local package) onto a self-hosted Dify, a plugin that requires a **newer** Dify version than the one running installs **without any warning or block**. The incompatibility only surfaces later at runtime — a node/tool fails (`PluginNotFoundError`, `PluginInvokeError`, or silent misbehavior) — which is hard to trace back to a version mismatch.
The plugin manifest already carries `meta.minimum_dify_version` for exactly this purpose, but today it is **write-only**: it is declared and format-validated, yet **no code path ever compares it against the running Dify version.**
### Evidence (paths as of 1.14.x; symbols are stable)
**a) The field is defined and only *format*-validated — never compared** — `api/core/plugin/entities/plugin.py`:
```python
class Meta(BaseModel):
minimum_dify_version: str | None = Field(default=None)
@field_validator("minimum_dify_version")
@classmethod
def validate_minimum_dify_version(cls, v: str | None) -> str | None:
if v is None:
return v
try:
Version(v) # only checks it parses as a version
return v
except InvalidVersion as e:
raise ValueError(f"Invalid version format: {v}") from e
```
A repo-wide search for `minimum_dify_version` returns only this definition + unit tests. No business logic reads it.
**b) Install/upgrade paths do not gate on it** — `api/services/plugin/plugin_service.py`: `install_from_local_pkg`, `install_from_github`, and `install_from_marketplace_pkg` only check marketplace-only permission and signature/source verification. Neither reads `declaration.meta.minimum_dify_version` nor compares the Dify version.
**c) The plugin daemon writes the field at scaffold time but never reads it at install time** — `cmd/commandline/plugin/init.go` writes it from `--min-dify-version` into `PluginMeta.MinimumDifyVersion` (`pkg/entities/plugin_entities/plugin_declaration.go`, no `validate` tag), but `internal/tasks/install_plugin.go` has no version-compatibility logic. The only real version comparison in the daemon (`internal/core/local_runtime/patch.go`) compares the **plugin SDK version** against hardcoded thresholds to patch old SDKs — unrelated to the host Dify version.
**d) The Marketplace already knows the caller's Dify version but does nothing version-aware with it** — `api/core/helper/marketplace.py` forwards the running version as a header on every call and displays whatever the server returns:
```python
headers={"X-Dify-Version": dify_config.project.version}
```
The client-side Marketplace response entity (`api/core/plugin/entities/marketplace.py`) exposes `latest_version` but has **no** `minimum_dify_version`, so the client couldn't filter or warn even if it wanted to.
## 2. Describe the feature you'd like to see
**The compatibility guarantee should live on the Marketplace/server side, not depend on clients upgrading Dify.** The server already receives `X-Dify-Version` on every request — it should use it:
1. **Version-aware Marketplace responses (primary ask).** Given the caller's `X-Dify-Version`, the Marketplace API should resolve to the **latest plugin version compatible with that Dify version** (not merely the global `latest_version`), and mark/withhold versions whose `minimum_dify_version` exceeds the caller's version. A self-hosted instance pinned to, say, 1.14.2 should be offered a working plugin build for 1.14.2 — never handed a build that silently can't run.
2. **Expose `minimum_dify_version` (and ideally a tested-compatibility range) in the Marketplace payload**, so any client can display a compatibility badge and disable install for incompatible builds.
3. **Install-time safety net (secondary).** As a backstop for GitHub/local-package installs that bypass the Marketplace, compare `declaration.meta.minimum_dify_version` with `dify_config.project.version` before finalizing install; block by default with an explicit message (e.g. `Plugin X requires Dify >= 1.15.0, current is 1.14.2`) plus an "install anyway" override.
Why server-side first: **self-hosted users realistically cannot upgrade Dify on demand** — upgrades carry data-migration and infra risk and are often pinned for stability. Telling them "upgrade Dify to use this plugin" is not an acceptable resolution. Serving a version-appropriate plugin build (or clearly saying none exists) keeps a pinned deployment working, and only needs the version signal the client already sends.
## 3. How will this feature improve your workflow/experience
- Turns a class of hard-to-diagnose runtime failures into an up-front, actionable state (compatible build served, or a clear "not available for your version").
- Removes the current "guess the right version pairing" burden users already carry (see linked threads).
- Makes the existing `minimum_dify_version` field meaningful for plugin authors instead of a silent no-op.
- Respects pinned self-hosted deployments instead of forcing Dify upgrades.
## 4. Additional context
Related symptom reports that server-side version awareness would have prevented:
- `langgenius/dify` #34275 — plugins stop working after a cross-version Dify upgrade.
- `langgenius/dify-plugin-daemon` #762 — local plugin then Marketplace update leads to *plugin not found*.
- `langgenius/dify-plugin-daemon` #696 — version pairing breaks plugin install after a daemon upgrade.
- discussion #34269 — users manually guessing which daemon/plugin version pairs with which Dify version.
Note on scope: the primary fix lives in the **hosted Marketplace API**, which is not in the open-source tree — so external contributors can't fully implement it, hence this is filed as an issue rather than a PR.
- [ ] I'm willing to help contribute the open-source portion (install-time backstop + console warning) if maintainers agree on the desired UX.
Contributor guide
Research direction
Start by reading api/services/plugin/plugin_service.py and the manifest entities in api/core/plugin/entities/plugin.py, then inspect internal/tasks/install_plugin.go and the Marketplace request handling described in api/core/helper/marketplace.py. Verify how existing version validation and installation paths work before defining the compatibility behavior. Done should include an explicit response or install-time outcome for incompatible versions, but the primary Marketplace API is outside this repository.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, python
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100