Skip to content

[Feature] Marketplace should handle plugin ↔ Dify version compatibility (minimum_dify_version is currently a no-op) #41048

Open

Description

@IFSimon

[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

  • I have searched for existing issues, including closed ones.
  • I confirm that I am using English to submit this report.
  • 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:

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:

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:

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.

Activity

  1. huhumeng2 commented on Sep 23, 2026

    @huhumeng2

    I investigated the open-source admission paths at bc94f7ead5cb0aa971d9e73563fdb49520feaf9b (reported Dify version 1.17.1). There is a narrower API-side gap worth separating from hosted Marketplace version selection.

    One update to the original report: the current Web code already compares minimum_dify_version in the local-package and Marketplace install UI, as well as the installed-plugin item. However, the corresponding PluginService installation methods do not compare the decoded manifest's minimum version with the host version before dispatching to the daemon.

    I ran an offline probe using real PluginService methods and validated PluginDeclaration / PluginDecodeResponse models. Only external boundaries—daemon, package download, installation-permission lookup and Redis—were replaced. Across local package, GitHub, cached Marketplace package and newly downloaded Marketplace package paths:

    Manifest minimum Host API service dispatched installation
    absent 1.17.1 4/4
    1.0.0 1.17.1 4/4
    999.0.0 1.17.1 4/4

    This confirms missing API-side admission; it does not claim that the real daemon installed or executed an incompatible plugin. No real package was downloaded or installed in this probe.

    Would a focused open-source PR be welcome for the following scope?

    • Add one compatibility policy owner and use the existing decoded manifests before dispatching installation or upgrade work.
    • Reject a declared minimum newer than a recognized host version, with an actionable error naming the required and current versions.
    • Preserve admission when no minimum is declared or the host meets it; keep the existing source/signature restrictions.
    • Validate all members of a batch before dispatching the installation task, and cover both cached and downloaded packages.
    • Exercise explicit upgrades and the existing background-upgrade caller through the same policy.

    Before implementation, I would like to align on custom/unparseable host version strings and whether an explicit override is desired. I would not introduce an implicit bypass. This would reference this issue rather than claim to close the hosted Marketplace version-selection request.

    AI assistance was used for investigation and the reproducible probe. The stated results were run against the revision above.

    From Codex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions