{"record":{"id":"d55a2f63ee0ca2dc","repo":"router-for-me/CLIProxyAPI","slug":"plugin-store-resolved-basic-auth-is-incomplete","errorCode":null,"errorMessage":"plugin store resolved basic auth is incomplete","messagePattern":"plugin store resolved basic auth is incomplete","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/auth.go","lineNumber":285,"sourceCode":"\t\theaders.Set(\"Authorization\", \"Bearer \"+token)\n\tdefault:\n\t\treturn false, fmt.Errorf(\"unsupported plugin store auth type %q\", item.Type)\n\t}\n\treturn true, nil\n}\n\nfunc applyResolvedPluginStoreAuth(headers http.Header, item ResolvedAuthConfig) (bool, error) {\n\tswitch strings.ToLower(strings.TrimSpace(item.Type)) {\n\tcase \"\", AuthTypeNone:\n\t\treturn false, nil\n\tcase AuthTypeBearer, AuthTypeGitHubToken:\n\t\tif len(item.Token) == 0 {\n\t\t\treturn false, fmt.Errorf(\"plugin store resolved auth token is empty\")\n\t\t}\n\t\theaders.Set(\"Authorization\", \"Bearer \"+string(item.Token))\n\tcase AuthTypeBasic:\n\t\tif len(item.Username) == 0 || len(item.Password) == 0 {\n\t\t\treturn false, fmt.Errorf(\"plugin store resolved basic auth is incomplete\")\n\t\t}\n\t\tcredential := make([]byte, 0, len(item.Username)+1+len(item.Password))\n\t\tcredential = append(credential, item.Username...)\n\t\tcredential = append(credential, ':')\n\t\tcredential = append(credential, item.Password...)\n\t\tencoded := base64.StdEncoding.EncodeToString(credential)\n\t\tfor index := range credential {\n\t\t\tcredential[index] = 0\n\t\t}\n\t\theaders.Set(\"Authorization\", \"Basic \"+encoded)\n\tcase AuthTypeHeader:\n\t\tif strings.TrimSpace(item.HeaderName) == \"\" {\n\t\t\treturn false, fmt.Errorf(\"plugin store resolved auth missing header-name\")\n\t\t}\n\t\tif len(item.HeaderValue) == 0 {\n\t\t\treturn false, fmt.Errorf(\"plugin store resolved auth header value is empty\")\n\t\t}\n\t\theaders.Set(item.HeaderName, string(item.HeaderValue))","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/auth.go#L267-L303","documentation":"The resolved-auth applier rejects basic auth when either Username or Password in ResolvedAuthConfig is empty. Both halves of the credential must be present before the Authorization: Basic header is built; the code also scrubs the intermediate credential buffer after encoding.","triggerScenarios":"A resolved store auth of type basic with a missing username or password: partial secret materialization, only one of the two referenced secrets resolving, or a management API payload containing just one field.","commonSituations":"Secret store holding username but the password entry was rotated/deleted; management updates that set username only; username/password resolution env vars where one is unset at resolution time.","solutions":["Provide both username and password in the resolved basic auth config","Check that both referenced secrets/env vars exist and resolve to non-empty values","If one side is genuinely unused, switch to an auth type that matches reality (e.g. header or bearer) instead of basic"],"exampleFix":"# before\n{\"auth\": {\"type\": \"basic\", \"username\": \"alice\"}}\n\n# after\n{\"auth\": {\"type\": \"basic\", \"username\": \"alice\", \"password\": \"<resolved-password>\"}}","handlingStrategy":"validation","validationCode":"if strings.EqualFold(strings.TrimSpace(item.Type), \"basic\") {\n    if len(item.Username) == 0 || len(item.Password) == 0 {\n        return fmt.Errorf(\"basic auth requires both username and password\")\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Submit username and password together when updating basic auth","After secret rotation, re-resolve both halves and re-validate before applying"],"tags":["config","plugin-store","auth","secrets","management-api"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}