{"record":{"id":"97d34f8f1ef654fa","repo":"github/copilot-sdk","slug":"builtinplugindirectories-must-contain-only-absolut-97d34f","errorCode":null,"errorMessage":"BuiltinPluginDirectories must contain only absolute paths: %s","messagePattern":"BuiltinPluginDirectories must contain only absolute paths: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/client.go","lineNumber":242,"sourceCode":"func NewClient(options *ClientOptions) *Client {\n\topts := ClientOptions{}\n\n\tclient := &Client{\n\t\toptions:              opts,\n\t\tstate:                stateDisconnected,\n\t\tsessions:             make(map[string]*Session),\n\t\tgitHubTokenProviders: make(map[string]GitHubTokenProvider),\n\t\tactualHost:           \"localhost\",\n\t\tisExternalServer:     false,\n\t\tuseStdio:             true,\n\t}\n\n\tif options != nil {\n\t\topts = *options\n\t}\n\tfor _, path := range opts.BuiltinPluginDirectories {\n\t\tif !filepath.IsAbs(path) {\n\t\t\tpanic(fmt.Sprintf(\"BuiltinPluginDirectories must contain only absolute paths: %s\", path))\n\t\t}\n\t}\n\topts.BuiltinPluginDirectories = append([]string(nil), opts.BuiltinPluginDirectories...)\n\n\t// Resolve the connection. An explicit connection always wins; otherwise\n\t// honor the same process/environment override as the other SDKs.\n\tconnection := opts.Connection\n\tif connection == nil {\n\t\tenv := opts.Env\n\t\tif env == nil {\n\t\t\tenv = os.Environ()\n\t\t}\n\t\tconnection = resolveDefaultConnection(env)\n\t}\n\tswitch conn := connection.(type) {\n\tcase StdioConnection:\n\t\tclient.useStdio = true\n\t\tclient.cliPath = conn.Path","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/client.go#L224-L260","documentation":"NewClient panics when any entry in ClientOptions.BuiltinPluginDirectories is a relative path. The SDK passes these directories to the native runtime, which resolves them independently of the Go process, so all entries must be absolute to be unambiguous.","triggerScenarios":"Calling NewClient with Options.BuiltinPluginDirectories containing a value like \"plugins/builtin\" or \"./x\" — any path where filepath.IsAbs fails. Panic raised at go/client.go:242.","commonSituations":"Building the list from config files or CLI flags that carry relative paths; developing on a machine where the working directory happens to make the relative path look correct.","solutions":["Convert each entry with filepath.Abs(path) before passing it to NewClient.","Fix the source of the paths (config file, flag) to supply absolute paths.","Reject relative paths at your own config-validation layer with a clear message."],"exampleFix":"// before\ndirs := []string{\"plugins/builtin\"}\nclient := clientpkg.NewClient(&clientpkg.Options{BuiltinPluginDirectories: dirs})\n// after\nvar dirs []string\nfor _, p := range []string{\"plugins/builtin\"} {\n    abs, err := filepath.Abs(p)\n    if err != nil {\n        panic(err)\n    }\n    dirs = append(dirs, abs)\n}\nclient := clientpkg.NewClient(&clientpkg.Options{BuiltinPluginDirectories: dirs})","handlingStrategy":"validation","validationCode":"for _, p := range opts.BuiltinPluginDirectories {\n    if !filepath.IsAbs(p) {\n        abs, err := filepath.Abs(p)\n        if err != nil { return err }\n        _ = abs // or reject the path\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always run filepath.Abs on user/config-supplied plugin paths at load time.","Prefer resolving paths once at startup, not deep in the client.","Add a unit test asserting configured plugin dirs are absolute."],"tags":["go","panic","paths","validation","plugins"],"backgroundTag":"invalid-argument-value","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}