{"record":{"id":"b23a239204e8e044","repo":"thanos-io/thanos","slug":"getting-absolute-file-path","errorCode":null,"errorMessage":"getting absolute file path","messagePattern":"getting absolute file path","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/extkingpin/path_content_reloader.go","lineNumber":47,"sourceCode":"func (n NopConfigContent) Content() ([]byte, error) {\n\treturn nil, nil\n}\n\n// Path returns an empty path.\nfunc (n NopConfigContent) Path() string {\n\treturn \"\"\n}\n\n// NewNopConfig creates a no-op config content (no configuration).\nfunc NewNopConfig() NopConfigContent {\n\treturn NopConfigContent{}\n}\n\n// PathContentReloader runs the reloadFunc when it detects that the contents of fileContent have changed.\nfunc PathContentReloader(ctx context.Context, fileContent fileContent, logger log.Logger, reloadFunc func(), debounceTime time.Duration) error {\n\tfilePath, err := filepath.Abs(fileContent.Path())\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"getting absolute file path\")\n\t}\n\n\tengine := &pollingEngine{\n\t\tfilePath:   filePath,\n\t\tlogger:     logger,\n\t\tdebounce:   debounceTime,\n\t\treloadFunc: reloadFunc,\n\t}\n\treturn engine.start(ctx)\n}\n\n// pollingEngine keeps rereading the contents at filePath and when its checksum changes it runs the reloadFunc.\ntype pollingEngine struct {\n\tfilePath         string\n\tlogger           log.Logger\n\tdebounce         time.Duration\n\treloadFunc       func()\n\tpreviousChecksum [sha256.Size]byte","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/extkingpin/path_content_reloader.go#L29-L65","documentation":"PathContentReloader resolves the watched file's relative path to an absolute one with filepath.Abs before setting up the polling engine. If filepath.Abs fails (it only errors when the process cannot determine its working directory), this wrapped error is returned. It is essentially a filesystem/process-environment failure at startup of the config reloader.","triggerScenarios":"Calling PathContentReloader (directly or via StartConfigReloader/newEndpointConfigProvider) with a fileContent whose Path() plus a deleted or unreadable current working directory causes filepath.Abs(workingDir, path) to fail (getwd error).","commonSituations":"Starting Thanos from a working directory that was deleted while the process launched (common with containers swapping filesystems), or running with a corrupted cwd.","solutions":["Restart the process from a valid, existing working directory.","Pass an absolute path to the file content so filepath.Abs does not need getwd.","Check that the container/pod's WORKDIR exists and is not deleted at runtime."],"exampleFix":"// before\nreloader, err := extkingpin.PathContentReloader(ctx, content, logger, reload, d) // cwd deleted\n// after\nabs, _ := filepath.Abs(cfgPath) // resolve while cwd is valid, then\ncontent := filestore.NewFileContent(abs)\nreloader, err := extkingpin.PathContentReloader(ctx, content, logger, reload, d)","handlingStrategy":"fallback","validationCode":"if _, err := os.Getwd(); err != nil { return fmt.Errorf(\"working directory unavailable: %w\", err) }","typeGuard":null,"tryCatchPattern":"if err := startConfigReloader(); err != nil { log.Error(err, \"falling back to static config, no reload\") }","preventionTips":["Pass absolute paths for watched config files","Ensure container WORKDIR exists and is not deleted","Check os.Getwd() early at process startup"],"tags":["filesystem","paths","config-reload"],"backgroundTag":"file-read-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}