{"record":{"id":"e320551b277aac60","repo":"router-for-me/CLIProxyAPI","slug":"install-type-q-is-not-direct","errorCode":null,"errorMessage":"install type %q is not direct","messagePattern":"install type %q is not direct","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/direct.go","lineNumber":16,"sourceCode":"package pluginstore\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc SelectArtifact(plan InstallPlan, goos string, goarch string) (Artifact, error) {\n\tplan = NormalizeInstallPlan(plan)\n\tgoos = normalizeGOOS(goos)\n\tgoarch = normalizeGOARCH(goarch)\n\tif plan.Type != InstallTypeDirect {\n\t\treturn Artifact{}, fmt.Errorf(\"install type %q is not direct\", plan.Type)\n\t}\n\tfor _, artifact := range plan.Artifacts {\n\t\tif artifact.GOOS == goos && artifact.GOARCH == goarch {\n\t\t\treturn artifact, nil\n\t\t}\n\t}\n\treturn Artifact{}, fmt.Errorf(\"artifact not found for %s/%s\", goos, goarch)\n}\n\nfunc (c Client) DownloadArtifact(ctx context.Context, artifact Artifact) ([]byte, error) {\n\tartifact = NormalizeInstallPlan(InstallPlan{Type: InstallTypeDirect, Artifacts: []Artifact{artifact}}).Artifacts[0]\n\tif errValidate := ValidateArtifact(artifact); errValidate != nil {\n\t\treturn nil, errValidate\n\t}\n\tmaxSize := int64(0)\n\tif artifact.Size > 0 {\n\t\tmaxSize = artifact.Size\n\t}","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/direct.go#L1-L34","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nartifact, err := pluginstore.SelectArtifact(plan, runtime.GOOS, runtime.GOARCH)\n// panics path for github-type plans -> 'install type \"github\" is not direct'\n\n// after\nswitch plan.Type {\ncase pluginstore.InstallTypeDirect:\n    artifact, err = pluginstore.SelectArtifact(plan, runtime.GOOS, runtime.GOARCH)\ncase pluginstore.InstallTypeGitHub:\n    artifact, err = selectGitHubArtifact(ctx, client, plan, runtime.GOOS, runtime.GOARCH)\ndefault:\n    return fmt.Errorf(\"unsupported install type %q\", plan.Type)\n}","handlingStrategy":"type-guard","validationCode":"plan = pluginstore.NormalizeInstallPlan(plan)\nif plan.Type != pluginstore.InstallTypeDirect {\n    return fmt.Errorf(\"plan type %q needs a non-direct installer\", plan.Type)\n}","typeGuard":"func isDirectPlan(plan pluginstore.InstallPlan) bool {\n    return pluginstore.NormalizeInstallPlan(plan).Type == pluginstore.InstallTypeDirect\n}","tryCatchPattern":null,"preventionTips":["Switch on plan.Type before selecting an installer strategy.","Validate plugin manifests at load time so unknown install types fail early with context."],"tags":["install-plan","artifact-selection","plugin-store","validation"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}