{"record":{"id":"354ede32204d9e80","repo":"router-for-me/CLIProxyAPI","slug":"core-auth-manager-unavailable","errorCode":null,"errorMessage":"core auth manager unavailable","messagePattern":"core auth manager unavailable","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/api/handlers/management/auth_files_fields.go","lineNumber":121,"sourceCode":"\t\t\t\"excluded_pattern\": configAPIKeyDisablePattern,\n\t\t})\n\t\treturn\n\t}\n\n\tapplyAuthDisabledState(targetAuth, *req.Disabled)\n\tif _, err := h.authManager.Update(ctx, targetAuth); err != nil {\n\t\tc.JSON(http.StatusInternalServerError, gin.H{\"error\": fmt.Sprintf(\"failed to update auth: %v\", err)})\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, gin.H{\"status\": \"ok\", \"disabled\": *req.Disabled})\n}\n\n// patchPluginVirtualSourceStatus toggles disabled on a plugin multi-auth source file and all\n// runtime auths expanded from it. Virtual project children cannot be toggled independently.\nfunc (h *Handler) patchPluginVirtualSourceStatus(ctx context.Context, targetAuth *coreauth.Auth, disabled bool) error {\n\tif h == nil || h.authManager == nil || targetAuth == nil {\n\t\treturn fmt.Errorf(\"core auth manager unavailable\")\n\t}\n\tsourcePath := strings.TrimSpace(authAttribute(targetAuth, coreauth.AttributeVirtualSource))\n\tif sourcePath == \"\" {\n\t\tsourcePath = strings.TrimSpace(authAttribute(targetAuth, \"path\"))\n\t}\n\tif sourcePath == \"\" {\n\t\treturn errPluginVirtualAuth\n\t}\n\tif errWrite := setSourceAuthFileDisabled(sourcePath, disabled); errWrite != nil {\n\t\tif os.IsNotExist(errWrite) {\n\t\t\treturn errAuthFileNotFound\n\t\t}\n\t\treturn fmt.Errorf(\"failed to update source auth file: %w\", errWrite)\n\t}\n\tnow := time.Now()\n\tfor _, auth := range h.authManager.List() {\n\t\tif auth == nil {\n\t\t\tcontinue","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/api/handlers/management/auth_files_fields.go#L103-L139","documentation":"patchPluginVirtualSourceStatus refuses to operate when h, h.authManager, or targetAuth is nil. The core auth manager is the runtime credential registry; without it the handler cannot enumerate or update the auths expanded from a plugin multi-auth source file, so toggling disabled state is aborted before touching disk.","triggerScenarios":"A PATCH request to toggle a plugin virtual auth's disabled flag on a handler constructed without an injected auth manager — unit tests building Handler{} directly, or an initialization-order bug where management routes are registered before the auth manager is set on the handler.","commonSituations":"Embedding the SDK and wiring management routes manually while skipping the auth-manager dependency; refactors that add a new Handler constructor path without propagating the manager; test harnesses hitting management endpoints in isolation.","solutions":["Ensure the management Handler is built via the standard constructor that injects the auth manager (check where Handler is assembled in internal/api)","If embedding the SDK, pass the service's auth manager before registering management routes","In tests, construct the handler with a real or fake auth manager instead of a zero-value Handler","Retry the toggle after the server fully initializes (the manager is set during service startup)"],"exampleFix":"// before\nh := &management.Handler{} // no auth manager\n// after\nh := management.NewHandler(service.AuthManager(), service.Config())","handlingStrategy":"type-guard","validationCode":"if h == nil || h.authManager == nil {\n    return errors.New(\"management handler not wired: auth manager missing — check service init order\")\n}","typeGuard":"func (h *Handler) ready() bool { return h != nil && h.authManager != nil }","tryCatchPattern":null,"preventionTips":["Construct handlers only via constructors that inject all dependencies","Assert at startup that the auth manager is set before routes serve","In tests, always inject a fake auth manager"],"tags":["initialization","dependency-injection","auth","management-api"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}