{"record":{"id":"b663d1e0f49e748b","repo":"wavetermdev/waveterm","slug":"path-must-be-absolute-got-relative-path-s-b663d1","errorCode":null,"errorMessage":"path must be absolute, got relative path: %s","messagePattern":"path must be absolute, got relative path: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/tools_readfile.go","lineNumber":212,"sourceCode":"\t\treturn true, \"Git credentials file\"\n\t}\n\n\treturn false, \"\"\n}\n\nfunc verifyReadTextFileInput(input any, toolUseData *uctypes.UIMessageDataToolUse) error {\n\tparams, err := parseReadTextFileInput(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\texpandedPath, err := wavebase.ExpandHomeDir(params.Filename)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to expand path: %w\", err)\n\t}\n\n\tif !filepath.IsAbs(expandedPath) {\n\t\treturn fmt.Errorf(\"path must be absolute, got relative path: %s\", params.Filename)\n\t}\n\n\tif blocked, reason := isBlockedFile(expandedPath); blocked {\n\t\treturn fmt.Errorf(\"access denied: potentially sensitive file: %s\", reason)\n\t}\n\n\tfileInfo, err := os.Stat(expandedPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to stat file: %w\", err)\n\t}\n\n\tif fileInfo.IsDir() {\n\t\treturn fmt.Errorf(\"path is a directory, cannot be read with the read_text_file tool. use the read_dir tool if available to read directories\")\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/tools_readfile.go#L194-L230","documentation":"read_text_file only accepts absolute paths. After ExpandHomeDir resolves the filename, verifyReadTextFileInput checks filepath.IsAbs and rejects relative paths. This prevents reads that silently depend on the server process's working directory.","triggerScenarios":"Calling read_text_file with {\"filename\": \"config.json\"} or \"./config.json\" where expansion leaves the path relative.","commonSituations":"Agents working from a repo root assuming cwd-relative reads; symlinks or env drift making what was absolute relative; Windows paths passed without a drive letter.","solutions":["Prefix the filename with \"/\" (or a Windows drive root).","Use \"~/...\" so ExpandHomeDir produces an absolute path.","Run filepath.IsAbs(expandedPath) in the caller before invoking the tool."],"exampleFix":"// before\n{\"filename\": \"./config/settings.json\"}\n// after\n{\"filename\": \"/home/user/project/config/settings.json\"}","handlingStrategy":"validation","validationCode":"const abs = require('path').isAbsolute(p) || p.startsWith('~');\nif (!abs) throw new Error(\"use an absolute path for read_text_file\");","typeGuard":"func isAbsAfterExpansion(p string) bool {\n    exp, err := wavebase.ExpandHomeDir(p)\n    return err == nil && filepath.IsAbs(exp)\n}","tryCatchPattern":"if err := verifyReadTextFileInput(params); err != nil {\n    if strings.Contains(err.Error(), \"path must be absolute\") {\n        // convert to absolute via filepath.Abs or cwd prefix, then retry\n    }\n}","preventionTips":["Resolve relative paths against an explicit root before calling","Never rely on the server process cwd","On Windows include the drive letter in paths sent to the tool"],"tags":["filesystem","path-validation","tooling"],"backgroundTag":"relative-path-not-allowed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}