router-for-me/CLIProxyAPI · error

direct install plugin %q resolved as %q

Error message

direct install plugin %q resolved as %q

What it means

Returned when the plugin IS found in the source registry but PluginInstallType(resolved) is not InstallTypeDirect — for example the registry entry is published as a github-release install. Direct install requires the source registry to also describe the plugin as direct-type so that artifact URLs can be resolved from the registry itself; a type mismatch means the resolution path is inconsistent with the requested install mode.

Source

Thrown at internal/pluginstore/install.go:206

	sourceURL := strings.TrimSpace(manifest.SourceURL)
	if sourceURL == "" {
		sourceURL = strings.TrimSpace(c.RegistryURL)
	}
	if sourceURL == "" {
		return Plugin{}, fmt.Errorf("direct install manifest missing source-url")
	}
	sourceClient := c
	sourceClient.RegistryURL = sourceURL
	registry, errRegistry := sourceClient.FetchRegistry(ctx)
	if errRegistry != nil {
		return Plugin{}, fmt.Errorf("fetch direct install source: %w", errRegistry)
	}
	resolved, okPlugin := registry.PluginByID(manifest.ID)
	if !okPlugin {
		return Plugin{}, fmt.Errorf("direct install plugin %q not found in source", strings.TrimSpace(manifest.ID))
	}
	if PluginInstallType(resolved) != InstallTypeDirect {
		return Plugin{}, fmt.Errorf("direct install plugin %q resolved as %q", strings.TrimSpace(manifest.ID), PluginInstallType(resolved))
	}
	return directPluginVersion(resolved, manifest.ID, manifest.Version)
}

func directPluginVersion(plugin Plugin, id string, version string) (Plugin, error) {
	id = strings.TrimSpace(id)
	version = normalizeVersion(version)
	if normalizeVersion(plugin.Version) == version {
		plugin.Version = version
		plugin.Install = NormalizeInstallPlan(plugin.Install)
		plugin.Install.Type = InstallTypeDirect
		if errPlan := ValidateInstallPlan(plugin.Install); errPlan != nil {
			return Plugin{}, fmt.Errorf("direct install plugin %q version %q: %w", id, version, errPlan)
		}
		return plugin, nil
	}
	for _, candidate := range plugin.Versions {
		if normalizeVersion(candidate.Version) != version {

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Check the plugin's install type in the source registry and use the matching install API (e.g. the GitHub release install path instead of direct)
  2. Update the source registry entry so the plugin is published with direct install type
  3. Update manifest.SourceURL to the registry that publishes the plugin as direct-type

Example fix

// before: registry says install.type = "github-release"
plugin, err := client.ResolveDirect(ctx, manifest) // "resolved as \"github-release\""

// after: use the install path matching the published type
result, err := client.InstallFromGitHubRelease(ctx, plugin, options) // or fix the registry entry to type "direct"
Defensive patterns

Strategy: validation

Validate before calling

func pluginIsDirectType(ctx context.Context, c pluginstore.Client, id string) (bool, error) {
    reg, err := c.FetchRegistry(ctx)
    if err != nil {
        return false, err
    }
    p, ok := reg.PluginByID(strings.TrimSpace(id))
    if !ok {
        return false, errors.New("plugin not in registry")
    }
    return pluginstore.PluginInstallType(p) == pluginstore.InstallTypeDirect, nil
}

Type guard

func isInstallTypeMismatch(err error) bool {
    return err != nil && strings.Contains(err.Error(), "resolved as")
}

Try / catch

if err != nil {
    if isInstallTypeMismatch(err) {
        // branch to the install API matching the published type
    }
}

Prevention

When it happens

Trigger: Manifest requests direct install, source registry publishes the same plugin ID with install type "github-release" (or any non-direct type). Happens when a plugin switched distribution models, or when SourceURL points at a registry that re-publishes the plugin differently.

Common situations: Upstream plugin migrated from registry-hosted artifacts to GitHub releases while local manifests still request direct install; mixing staging registry (direct) with production registry (github-release); registry entry edited to change install type.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/e80552b3a86e0504. Report an issue: GitHub.