{"record":{"id":"96dbf6382ce91adf","repo":"router-for-me/CLIProxyAPI","slug":"artifact-not-found-for-s-s","errorCode":null,"errorMessage":"artifact not found for %s/%s","messagePattern":"artifact not found for (.+?)/(.+?)","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/direct.go","lineNumber":23,"sourceCode":"\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}\n\tdata, errDownload := c.get(ctx, artifact.URL, \"application/octet-stream\", RequestKindArtifact, maxSize)\n\tif errDownload != nil {\n\t\treturn nil, errDownload\n\t}\n\tif maxSize > 0 && int64(len(data)) > maxSize {\n\t\treturn nil, fmt.Errorf(\"artifact exceeds declared size\")\n\t}","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/direct.go#L5-L41","documentation":"SelectArtifact iterates the plan's normalized artifact list looking for one whose GOOS and GOARCH match the supplied values. It throws 'artifact not found for %s/%s' when no artifact entry covers the caller's platform pair (e.g. linux/arm64). Both inputs are normalized first, so the error text shows the canonical GOOS/GOARCH that failed to match.","triggerScenarios":"Calling SelectArtifact with a GOOS/GOARCH pair not present in plan.Artifacts — e.g. the plugin publishes darwin/amd64, linux/amd64, windows/amd64 but the caller runs linux/arm64; or an artifacts list that is empty after normalization.","commonSituations":"Installing a plugin on Apple Silicon (darwin/arm64) when the publisher only shipped amd64 builds; running on rarer platforms (freebsd, linux/386); a manifest that lists artifacts without goos/goarch fields so nothing matches; passing raw runtime values like \"darwin\" with an unexpected casing (normalization usually fixes this, so a genuine gap is the remaining cause).","solutions":["Inspect the plugin manifest's artifacts list and confirm it contains an entry for your runtime.GOOS/runtime.GOARCH.","If you control the plugin, publish and declare a binary for the missing platform (e.g. add a linux/arm64 artifact).","If running under emulation, pass the goos/goarch of the binary you actually want (e.g. amd64 under Rosetta) rather than the host pair.","Fall back to a source build path for the plugin if one is available."],"exampleFix":"// before\nartifact, err := pluginstore.SelectArtifact(plan, runtime.GOOS, runtime.GOARCH)\n// on linux/arm64: 'artifact not found for linux/arm64'\n\n// after\nsupported := map[string]bool{}\nfor _, a := range plan.Artifacts {\n    supported[a.GOOS+\"/\"+a.GOARCH] = true\n}\nif !supported[runtime.GOOS+\"/\"+runtime.GOARCH] {\n    return fmt.Errorf(\"plugin does not support %s/%s; supported: %v\", runtime.GOOS, runtime.GOARCH, supported)\n}\nartifact, err := pluginstore.SelectArtifact(plan, runtime.GOOS, runtime.GOARCH)","handlingStrategy":"validation","validationCode":"supported := map[string]bool{}\nfor _, a := range pluginstore.NormalizeInstallPlan(plan).Artifacts {\n    supported[a.GOOS+\"/\"+a.GOARCH] = true\n}\nif !supported[runtime.GOOS+\"/\"+runtime.GOARCH] {\n    return fmt.Errorf(\"plugin lacks %s/%s build; have %v\", runtime.GOOS, runtime.GOARCH, supported)\n}","typeGuard":"func planSupports(plan pluginstore.InstallPlan, goos, goarch string) bool {\n    for _, a := range pluginstore.NormalizeInstallPlan(plan).Artifacts {\n        if a.GOOS == goos && a.GOARCH == goarch {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Surface the supported platform list in error messages to users.","Publish artifacts for the platforms your users run (include arm64) or provide a source fallback."],"tags":["platform-support","artifact-selection","goos","goarch","plugin-store"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}