Skip to content

fix: coerce numeric plugin metadata version to string - #10001

Open
unknowbug wants to merge 2 commits into
AstrBotDevs:masterfrom
unknowbug:fix/plugin-metadata-numeric-version
Open

unknowbug wants to merge 2 commits into
AstrBotDevs:masterfrom
unknowbug:fix/plugin-metadata-numeric-version

Conversation

@unknowbug

@unknowbug unknowbug commented Sep 9, 2026

Copy link
Copy Markdown

Motivation / 动机

Plugin upgrades fail with metadata.yaml 中字段 version 必须是非空字符串。 for any plugin whose metadata.yaml uses an unquoted numeric version, which is extremely common in the plugin ecosystem:

version: 2.4

YAML parses 2.4 as a float, and the strict metadata validation added recently requires every required field to be a non-empty str, so the upgrade is rejected.

Bug report info (following the issue template)

问题描述 / Problem

Upgrading a plugin (e.g. astrbot_plugin_comfyui_pro) fails after the update archive is downloaded. The zip is left behind in the plugins directory and the installed plugin is never replaced.

如何复现 / How to reproduce

  1. Install any plugin whose metadata.yaml contains an unquoted numeric version (e.g. version: 2.4).
  2. In WebUI, click "更新" (update) on the plugin.
  3. The update fails with: 插件校验失败:metadata.yaml 中字段 version 必须是非空字符串。

AstrBot 版本 / Version: v4.27.4

操作系统 / OS: Windows

部署方式 / Deployment: uv tool install

错误日志 / Error log

Exception: 插件校验失败:metadata.yaml 中字段 version 必须是非空字符串。

(No stack-level log is emitted because validation raises before any error logging.)

Modifications / 改动点

  • astrbot/core/star/updater.pyvalidate_plugin_metadata() now coerces numeric scalars (int/float, excluding bool) for required fields to strings and writes the coercion back to the caller's dict, so both archive/install-time validation and later StarMetadata loading see a string version.

  • tests/test_plugin_manager.py — two regression tests:

    • test_validate_plugin_metadata_coerces_numeric_version_to_string
    • test_load_plugin_metadata_coerces_numeric_version_to_string (end-to-end: write a plugin with unquoted version: 2.4, load it via PluginManager._load_plugin_metadata, assert version == "2.4")
  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

Verified against a real-world plugin archive (astrbot_plugin_comfyui_pro-2.4-5878cf8d60f7.zip, which previously failed validation):

zip validation OK, metadata entry = .../metadata.yaml
version = '2.4' str

End-to-end check of PluginManager._load_plugin_metadata() with an unquoted version: 2.4:

direct coercion OK
load coercion OK, version = '2.4'

Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了"验证步骤"和"运行截图"

  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。

  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。

Summary by Sourcery

Preserve plugin version text during YAML parsing so plugins using unquoted numeric versions can be validated and upgraded successfully.

Bug Fixes:

  • Allow plugin metadata with unquoted numeric versions to pass validation and load as string values without losing trailing zeros.

Enhancements:

  • Use a plugin-specific YAML loader that preserves scalar source text across metadata inspection, installation, updates, and runtime loading.

Tests:

  • Add regression coverage for numeric version coercion and preservation of trailing-zero versions during plugin metadata loading.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="astrbot/core/star/updater.py" line_range="357-359" />
<code_context>
+        # reading the original metadata (e.g. StarMetadata loading) see a str.
+        for field in PLUGIN_METADATA_REQUIRED_FIELDS:
+            value = normalized_metadata.get(field)
+            if isinstance(value, (int, float)) and not isinstance(value, bool):
+                normalized_metadata[field] = str(value)
+                metadata[field] = str(value)
+
         missing_fields = [
</code_context>
<issue_to_address>
**issue (bug_risk):** A YAML version such as `version: 2.10` is parsed as the float `2.1`, and `str(value)` permanently converts it to the incorrect version string `"2.1"`. The installed plugin then reports and compares a different version from the one written by the plugin author.

**Triggers:** When an unquoted numeric version contains trailing zeroes or otherwise depends on its original lexical representation.

**Suggested fix:** Preserve the original YAML scalar text when coercing versions, or reject ambiguous numeric versions and require a quoted string instead of converting the already-rounded float.
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: astrbot/core/star/updater.py:359


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread astrbot/core/star/updater.py

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

@unknowbug
unknowbug force-pushed the fix/plugin-metadata-numeric-version branch from 1219f7f to 5683474 Compare September 15, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant