router-for-me/CLIProxyAPI · error
install type %q is not direct
Error message
install type %q is not direct
What it means
SelectArtifact picks the direct-download artifact matching the runtime GOOS/GOARCH from an InstallPlan. It throws 'install type %q is not direct' when the normalized plan's Type is anything other than "direct" (InstallTypeDirect). The function is the artifact selector for the direct install strategy only; GitHub-release-based or source-install plans are rejected up front.
Source
Thrown at internal/pluginstore/direct.go:16
package pluginstore
import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"strings"
)
func SelectArtifact(plan InstallPlan, goos string, goarch string) (Artifact, error) {
plan = NormalizeInstallPlan(plan)
goos = normalizeGOOS(goos)
goarch = normalizeGOARCH(goarch)
if plan.Type != InstallTypeDirect {
return Artifact{}, fmt.Errorf("install type %q is not direct", plan.Type)
}
for _, artifact := range plan.Artifacts {
if artifact.GOOS == goos && artifact.GOARCH == goarch {
return artifact, nil
}
}
return Artifact{}, fmt.Errorf("artifact not found for %s/%s", goos, goarch)
}
func (c Client) DownloadArtifact(ctx context.Context, artifact Artifact) ([]byte, error) {
artifact = NormalizeInstallPlan(InstallPlan{Type: InstallTypeDirect, Artifacts: []Artifact{artifact}}).Artifacts[0]
if errValidate := ValidateArtifact(artifact); errValidate != nil {
return nil, errValidate
}
maxSize := int64(0)
if artifact.Size > 0 {
maxSize = artifact.Size
}View on GitHub (pinned to 78f0c4079e)
Solutions
- Route the plan by type first: only call SelectArtifact when plan.Type == "direct"; use the GitHub release flow for github-type plans.
- Check the plugin manifest's install.type field for typos and set it to "direct" if the plugin publishes plain platform binaries.
- Log plan.Type before calling SelectArtifact to see the exact non-direct value being passed.
Example fix
// before
artifact, err := pluginstore.SelectArtifact(plan, runtime.GOOS, runtime.GOARCH)
// panics path for github-type plans -> 'install type "github" is not direct'
// after
switch plan.Type {
case pluginstore.InstallTypeDirect:
artifact, err = pluginstore.SelectArtifact(plan, runtime.GOOS, runtime.GOARCH)
case pluginstore.InstallTypeGitHub:
artifact, err = selectGitHubArtifact(ctx, client, plan, runtime.GOOS, runtime.GOARCH)
default:
return fmt.Errorf("unsupported install type %q", plan.Type)
} Defensive patterns
Strategy: type-guard
Validate before calling
plan = pluginstore.NormalizeInstallPlan(plan)
if plan.Type != pluginstore.InstallTypeDirect {
return fmt.Errorf("plan type %q needs a non-direct installer", plan.Type)
} Type guard
func isDirectPlan(plan pluginstore.InstallPlan) bool {
return pluginstore.NormalizeInstallPlan(plan).Type == pluginstore.InstallTypeDirect
} Prevention
- Switch on plan.Type before selecting an installer strategy.
- Validate plugin manifests at load time so unknown install types fail early with context.
When it happens
Trigger: Calling SelectArtifact(plan, goos, goarch) with plan.Type set to a non-direct value such as "github", "source", or the empty string after NormalizeInstallPlan. This happens when a plugin manifest declares a non-direct install strategy but the caller routes it through the direct-download code path.
Common situations: Plugin index entries whose manifest uses a github release strategy being passed to the direct installer; typos in the `type` field of a plugin manifest (e.g. "Direct" is not normalized if unsupported); routing logic that does not switch on plan.Type before calling SelectArtifact.
Related errors
- direct install plugin %q version %q: %w
- plugin store auth missing header-name
- unsupported plugin store auth type %q
- plugin store resolved auth missing header-name
- invalid plugin store url
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/e320551b277aac60.
Report an issue: GitHub.