Plugin without version defaults to "latest" causing semver parsing error #8528

Open
opened 2026-02-16 18:10:12 -05:00 by yindo · 2 comments
Owner

Originally created by @bdwelle on GitHub (Feb 4, 2026).

Originally assigned to: @rekram1-node on GitHub.

Bug Description

When a plugin is specified in opencode.json without a version suffix (e.g., \"opencode-gemini-auth\" instead of \"opencode-gemini-auth@1.3.8\"), opencode defaults the version to the string \"latest\". However, this causes a semver parsing error because \"latest\" is not a valid SemVer string.

Location

File: packages/opencode/src/plugin/index.ts
Lines: 57-58

const lastAtIndex = plugin.lastIndexOf(\"@\")
const version = lastAtIndex > 0 ? plugin.substring(lastAtIndex + 1) : \"latest\"

Error Message

{
  \"name\": \"UnknownError\",
  \"data\": {
    \"message\": \"Error: Invalid SemVer: latest\\n\\n    at order (unknown)\\n    at isOutdated (src/bun/registry.ts:46:19)\\n    at processTicksAndRejections (native:7:39)\"
  }
}

Reproduction Steps

  1. Edit ~/.config/opencode/opencode.json
  2. Specify a plugin without version:
    {
      \"plugin\": [
        \"opencode-gemini-auth\"  // Missing @version
      ]
    }
    
  3. Run opencode
  4. Error occurs on startup

Expected Behavior

Either:

  1. Skip/ignore plugins without explicit versions
  2. Use a fallback that doesn't require semver parsing
  3. Validate versions before passing to semver and fail with a clear error message

Actual Behavior

Defaults version to \"latest\" string, which causes semver to fail with \"Invalid SemVer: latest\"

Root Cause

The code unconditionally defaults to \"latest\" when no version is found. This string is then passed to semver for version comparison, but semver requires valid SemVer format (e.g., 1.2.3, latest is not valid).

Workaround

Specify explicit version:

{
  \"plugin\": [
    \"opencode-gemini-auth@1.3.8\"
  ]
}

Notes

This can occur when third-party tools (e.g., tessl/skills installers) rewrite the config and strip version specifiers.

Originally created by @bdwelle on GitHub (Feb 4, 2026). Originally assigned to: @rekram1-node on GitHub. ## Bug Description When a plugin is specified in `opencode.json` without a version suffix (e.g., `\"opencode-gemini-auth\"` instead of `\"opencode-gemini-auth@1.3.8\"`), opencode defaults the version to the string `\"latest\"`. However, this causes a semver parsing error because `\"latest\"` is not a valid SemVer string. ## Location File: `packages/opencode/src/plugin/index.ts` Lines: 57-58 ```javascript const lastAtIndex = plugin.lastIndexOf(\"@\") const version = lastAtIndex > 0 ? plugin.substring(lastAtIndex + 1) : \"latest\" ``` ## Error Message ```json { \"name\": \"UnknownError\", \"data\": { \"message\": \"Error: Invalid SemVer: latest\\n\\n at order (unknown)\\n at isOutdated (src/bun/registry.ts:46:19)\\n at processTicksAndRejections (native:7:39)\" } } ``` ## Reproduction Steps 1. Edit `~/.config/opencode/opencode.json` 2. Specify a plugin without version: ```json { \"plugin\": [ \"opencode-gemini-auth\" // Missing @version ] } ``` 3. Run `opencode` 4. Error occurs on startup ## Expected Behavior Either: 1. Skip/ignore plugins without explicit versions 2. Use a fallback that doesn't require semver parsing 3. Validate versions before passing to semver and fail with a clear error message ## Actual Behavior Defaults version to `\"latest\"` string, which causes semver to fail with `\"Invalid SemVer: latest\"` ## Root Cause The code unconditionally defaults to `\"latest\"` when no version is found. This string is then passed to semver for version comparison, but semver requires valid SemVer format (e.g., `1.2.3`, `latest` is not valid). ## Workaround Specify explicit version: ```json { \"plugin\": [ \"opencode-gemini-auth@1.3.8\" ] } ``` ## Notes This can occur when third-party tools (e.g., tessl/skills installers) rewrite the config and strip version specifiers.
Author
Owner

@github-actions[bot] commented on GitHub (Feb 4, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #10355: opencode.json plugins version overwritten on startup (related version handling issue)
  • #8763: Plugin loader incorrectly appends @latest to GitHub references (similar issue with 'latest' version handling)
  • #6774: Plugins with implied latest version don't auto-update on restart (related to defaulting to 'latest' version)
  • #11130: plugins silently fail to load with bad syntax in opencode.json (related config parsing issue)

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Feb 4, 2026): This issue might be a duplicate of existing issues. Please check: - #10355: opencode.json plugins version overwritten on startup (related version handling issue) - #8763: Plugin loader incorrectly appends @latest to GitHub references (similar issue with 'latest' version handling) - #6774: Plugins with implied latest version don't auto-update on restart (related to defaulting to 'latest' version) - #11130: plugins silently fail to load with bad syntax in opencode.json (related config parsing issue) Feel free to ignore if none of these address your specific case.
Author
Owner

@R44VC0RP commented on GitHub (Feb 4, 2026):

Thanks for the detailed report @bdwelle! This is a confirmed bug.

Root Cause:

When a plugin is configured without a version (e.g., "opencode-gemini-auth"), the code defaults to "latest". During the first install, if the version resolution from the installed package's package.json fails (file missing, parse error, etc.), "latest" gets stored in the cache at ~/.cache/opencode/package.json.

On subsequent runs, when checking if the cached version is outdated, semver.order("latest", "x.y.z") throws because "latest" isn't a valid semver string.

Relevant code:

  • packages/opencode/src/bun/index.ts:130-139 - Version resolution can fail silently, leaving "latest" to be cached
  • packages/opencode/src/bun/registry.ts:46 - semver.order() call that throws

Workaround:

As you noted, specifying explicit versions works:

{ "plugin": ["opencode-gemini-auth@1.3.8"] }

You can also clear the cache: rm -rf ~/.cache/opencode/package.json

Fix:

We'll add validation in isOutdated() to handle invalid cached versions gracefully.

If you'd like to open a PR for this, we'd welcome the contribution!

@R44VC0RP commented on GitHub (Feb 4, 2026): Thanks for the detailed report @bdwelle! This is a confirmed bug. **Root Cause:** When a plugin is configured without a version (e.g., `"opencode-gemini-auth"`), the code defaults to `"latest"`. During the first install, if the version resolution from the installed package's `package.json` fails (file missing, parse error, etc.), `"latest"` gets stored in the cache at `~/.cache/opencode/package.json`. On subsequent runs, when checking if the cached version is outdated, `semver.order("latest", "x.y.z")` throws because `"latest"` isn't a valid semver string. **Relevant code:** - `packages/opencode/src/bun/index.ts:130-139` - Version resolution can fail silently, leaving `"latest"` to be cached - `packages/opencode/src/bun/registry.ts:46` - `semver.order()` call that throws **Workaround:** As you noted, specifying explicit versions works: ```json { "plugin": ["opencode-gemini-auth@1.3.8"] } ``` You can also clear the cache: `rm -rf ~/.cache/opencode/package.json` **Fix:** We'll add validation in `isOutdated()` to handle invalid cached versions gracefully. If you'd like to open a PR for this, we'd welcome the contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#8528