{"record":{"id":"38282c448cca1b67","repo":"OpenNHP/opennhp","slug":"fail-to-get-base-directory-absolute-path-w","errorCode":null,"errorMessage":"fail to get base directory absolute path: %w","messagePattern":"fail to get base directory absolute path: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/kbs/resource/resource.go","lineNumber":161,"sourceCode":"\t\t\"enc\": \"A256GCM\",\n\t}\n\tprotectedJSON, _ := json.Marshal(protected)\n\n\tresponse := map[string]string{\n\t\t\"protected\":     string(protectedJSON),\n\t\t\"encrypted_key\": base64.RawURLEncoding.EncodeToString(encryptedKey),\n\t\t\"iv\":            base64.RawURLEncoding.EncodeToString(iv),\n\t\t\"ciphertext\":    base64.RawURLEncoding.EncodeToString(encryptedContent),\n\t\t\"tag\":           \"\",\n\t}\n\n\tc.JSON(http.StatusOK, response)\n}\n\nfunc loadResource(resourceID string) ([]byte, error) {\n\tabsBaseDir, err := filepath.Abs(baseDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fail to get base directory absolute path: %w\", err)\n\t}\n\n\tfullPath := filepath.Join(absBaseDir, resourceID)\n\n\tabsFullPath, err := filepath.Abs(fullPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fail to get resource absolute path: %w\", err)\n\t}\n\n\t// Check if the path is within the base directory to avoid path traversal attack.\n\tif !strings.HasPrefix(absFullPath, absBaseDir) {\n\t\treturn nil, errors.New(\"invalid resource ID: potential path traversal attack\")\n\t}\n\n\tif _, statErr := os.Stat(absFullPath); statErr != nil {\n\t\tif os.IsNotExist(statErr) {\n\t\t\treturn nil, errors.New(\"resource not found\")\n\t\t}","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/kbs/resource/resource.go#L143-L179","documentation":"loadResource resolves the KBS resource base directory to an absolute path via filepath.Abs. This error is returned when filepath.Abs(baseDir) fails (wrapped as 'fail to get base directory absolute path: %w'). filepath.Abs only fails when os.Getwd fails, meaning the process working directory was deleted or is inaccessible.","triggerScenarios":"GetResource calls loadResource while the process's current working directory no longer exists (deleted/moved after start), making os.Getwd fail inside filepath.Abs.","commonSituations":"Daemon started in a temp directory that was later removed; running under a container with a stale workdir; systemd/chroot environments where the cwd is unmounted.","solutions":["Restore a valid working directory or restart the daemon from an existing directory","Set a stable WorkingDirectory in the service unit / WORKDIR in the container","Make baseDir an absolute value configured at startup so filepath.Abs is a no-op path","Cache the resolved base directory at init instead of per-request","Check the wrapped error to confirm getwd failure before deeper debugging"],"exampleFix":"// before\nabsBaseDir, err := filepath.Abs(baseDir)\nif err != nil {\n\treturn nil, fmt.Errorf(\"fail to get base directory absolute path: %w\", err)\n}\n// after (resolve once at init from an explicit absolute base)\nif !filepath.IsAbs(baseDir) {\n\treturn nil, fmt.Errorf(\"baseDir must be absolute, got %q\", baseDir)\n}\nabsBaseDir := baseDir","handlingStrategy":"validation","validationCode":"if !filepath.IsAbs(baseDir) {\n\treturn fmt.Errorf(\"baseDir must be configured as an absolute path, got %q\", baseDir)\n}\nif fi, err := os.Stat(baseDir); err != nil || !fi.IsDir() {\n\treturn fmt.Errorf(\"baseDir %q does not exist\", baseDir)\n}","typeGuard":null,"tryCatchPattern":"data, err := loadResource(resourceID)\nif err != nil {\n\tif strings.Contains(err.Error(), \"fail to get base directory absolute path\") {\n\t\thttp.Error(w, \"resource store unavailable\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\thttp.Error(w, \"resource not found\", http.StatusNotFound)\n\treturn\n}","preventionTips":["Configure baseDir as an absolute path at startup","Set a stable WorkingDirectory (systemd WorkingDirectory=, Docker WORKDIR)","Resolve the base directory once at init, not per request","Avoid starting daemons from temporary directories"],"tags":["go","filesystem","filepath"],"backgroundTag":"invalid-config-value","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}