{"record":{"id":"ffdcb48e9dc5986f","repo":"router-for-me/CLIProxyAPI","slug":"pluginhost-token-store-unavailable","errorCode":null,"errorMessage":"pluginhost: token store unavailable","messagePattern":"pluginhost: token store unavailable","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pluginhost/command_line.go","lineNumber":371,"sourceCode":"\t\treturn pluginapi.CommandLineExecutionResponse{}, nil\n\t}\n\tdefer func() {\n\t\tif recovered := recover(); recovered != nil {\n\t\t\th.fusePlugin(record.id, \"CommandLinePlugin.ExecuteCommandLine\", recovered)\n\t\t\tresp = pluginapi.CommandLineExecutionResponse{}\n\t\t\terr = fmt.Errorf(\"command-line execution panic: %v\", recovered)\n\t\t}\n\t}()\n\treturn plugin.ExecuteCommandLine(ctx, req)\n}\n\nfunc (h *Host) persistCommandLineAuths(ctx context.Context, auths []pluginapi.AuthData) ([]string, error) {\n\tif len(auths) == 0 {\n\t\treturn nil, nil\n\t}\n\tstore := sdkAuth.GetTokenStore()\n\tif store == nil {\n\t\treturn nil, fmt.Errorf(\"pluginhost: token store unavailable\")\n\t}\n\tsummary := h.hostConfigSummary()\n\tif summary.AuthDir != \"\" {\n\t\tif setter, okSetter := store.(interface{ SetBaseDir(string) }); okSetter {\n\t\t\tsetter.SetBaseDir(summary.AuthDir)\n\t\t}\n\t}\n\tsavedPaths := make([]string, 0, len(auths))\n\tfor index, authData := range auths {\n\t\trecord := h.AuthDataToCoreAuth(authData, \"\", \"\")\n\t\tif record == nil {\n\t\t\treturn savedPaths, fmt.Errorf(\"pluginhost: command-line auth %d is invalid\", index+1)\n\t\t}\n\t\tsavedPath, errSave := store.Save(ctx, record)\n\t\tif errSave != nil {\n\t\t\treturn savedPaths, fmt.Errorf(\"pluginhost: save command-line auth %s: %w\", record.ID, errSave)\n\t\t}\n\t\tif strings.TrimSpace(savedPath) != \"\" {","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginhost/command_line.go#L353-L389","documentation":"When a plugin's command-line execution returns auth data to persist, the host looks up the SDK token store via sdkAuth.GetTokenStore(). If no token store has been initialized in the process, persistence is aborted with this error and the plugin's returned credentials are not saved.","triggerScenarios":"Running a plugin command-line flow (plugin.ExecuteCommandLine returning non-empty auths) in a context where the SDK token store was never initialized — e.g. a minimal embedding of the SDK that skipped token store setup, or a host started in a mode that does not register a store.","commonSituations":"Embedding sdk/cliproxy in a custom binary without configuring auth persistence; running management/command-line tooling before the service fully initializes; a test harness that spins up the plugin host without the auth store.","solutions":["Initialize the token store before running command-line plugin flows (set it up via the SDK's builder/service initialization so GetTokenStore returns non-nil).","If embedding, follow the standard service bootstrap in sdk/cliproxy rather than constructing the plugin host standalone.","In tests, install an in-memory token store before invoking command-line execution."],"exampleFix":"// before: host runs command-line flow, store never initialized\nresp, err := host.ExecuteCommandLine(ctx, req)\n// persistCommandLineAuths -> \"pluginhost: token store unavailable\"\n\n// after: initialize the store during service bootstrap\nstore := filestore.New(authDir)\nsdkAuth.SetTokenStore(store) // or equivalent builder option\nresp, err := host.ExecuteCommandLine(ctx, req)","handlingStrategy":"validation","validationCode":"// Ensure the token store exists before running command-line flows\nif sdkAuth.GetTokenStore() == nil {\n    return fmt.Errorf(\"token store not initialized; initialize auth storage before plugin command-line flows\")\n}","typeGuard":"func tokenStoreReady() bool {\n    return sdkAuth.GetTokenStore() != nil\n}","tryCatchPattern":"paths, err := host.PersistCommandLineAuths(ctx, auths)\nif err != nil && strings.Contains(err.Error(), \"token store unavailable\") {\n    // Non-retryable setup error: initialize store, then re-run the whole command-line flow\n    return initializeStoreAndRetry()\n}","preventionTips":["Bootstrap auth storage during service init, before any plugin is loaded.","In embeddings, use the full sdk/cliproxy builder so the token store is always wired."],"tags":["plugin","auth","token-store","initialization","pluginhost"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}