{"record":{"id":"1388234f6182066e","repo":"gastownhall/beads","slug":"buildproxiedserverclientinfo-path-q-is-not-absol","errorCode":null,"errorMessage":"buildProxiedServerClientInfo: path %q is not absolute","messagePattern":"buildProxiedServerClientInfo: path %q is not absolute","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/init_proxied_server.go","lineNumber":478,"sourceCode":"\tcfg.DoltTeamServer = in.teamServer\n\n\tif filepath.IsAbs(cfg.DoltDataDir) {\n\t\tcfg.DoltDataDir = \"\"\n\t}\n\n\treturn json.MarshalIndent(cfg, \"\", \"  \")\n}\n\nfunc buildProxiedServerClientInfo(rootPath, configPath, logPath string, port int, idleTimeout time.Duration, external *configfile.ExternalDoltConfig) (*configfile.ProxiedServerClientInfo, error) {\n\tif rootPath == \"\" && configPath == \"\" && logPath == \"\" && port == 0 && idleTimeout == 0 && external == nil {\n\t\treturn nil, nil\n\t}\n\tclean := func(p string) (string, error) {\n\t\tif p == \"\" {\n\t\t\treturn \"\", nil\n\t\t}\n\t\tif !filepath.IsAbs(p) {\n\t\t\treturn \"\", fmt.Errorf(\"buildProxiedServerClientInfo: path %q is not absolute\", p)\n\t\t}\n\t\treturn filepath.Clean(p), nil\n\t}\n\trootAbs, err := clean(rootPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconfigAbs, err := clean(configPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tlogAbs, err := clean(logPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif external != nil {\n\t\tif err := external.Validate(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"buildProxiedServerClientInfo: %w\", err)","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/init_proxied_server.go#L460-L496","documentation":"buildProxiedServerClientInfo assembles the client-side info for the proxied server (root path, config path, log path). Each supplied path must be absolute because the spawned server process may run with a different working directory; clean() rejects relative paths with this error. Empty paths are allowed and skipped.","triggerScenarios":"Calling bd init (or the code path that builds ProxiedServerClientInfo) with a relative rootPath, configPath, or logPath — e.g. passing \"./.bd\" or \"bd.log\" instead of an absolute path.","commonSituations":"Scripts using relative paths assuming init's cwd; passing $PWD-derived values after a cd; wrappers invoking the internal API with user-typed relative paths.","solutions":["Convert all supplied paths to absolute before init, e.g. with filepath.Abs or by prefixing the known root","Have the caller resolve relative paths against the intended root instead of assuming the server's cwd","Check which of rootPath/configPath/logPath was relative from the %q in the error message"],"exampleFix":"// before\nbuildProxiedServerClientInfo(\"./.bd\", cfgPath, logPath, ...)\n// error: path \"./.bd\" is not absolute\n// after\nroot, _ := filepath.Abs(\"./.bd\")\nbuildProxiedServerClientInfo(root, cfgPath, logPath, ...)","handlingStrategy":"validation","validationCode":"func mustAbs(p string) (string, error) {\n    if p == \"\" { return \"\", nil }\n    abs, err := filepath.Abs(p)\n    if err != nil { return \"\", err }\n    if !filepath.IsAbs(abs) { return \"\", fmt.Errorf(\"path %q not absolute\", p) }\n    return abs, nil\n}","typeGuard":"func isAbsPath(p string) bool { return p == \"\" || filepath.IsAbs(p) }","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"is not absolute\") {\n    var pe *filepathError\n    if errors.As(err, &pe) {\n        abs, aerr := filepath.Abs(pe.Path)\n        if aerr == nil { /* retry with abs */ }\n    }\n}","preventionTips":["Always normalize user-supplied paths with filepath.Abs before building client info","Never assume the spawned server shares your cwd","Empty paths are valid (skipped) — only non-empty paths must be absolute","Include which path failed in your own error wrapping when calling this API"],"tags":["init","paths","validation","proxied-server","absolute-path"],"backgroundTag":"relative-path-not-allowed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}