{"record":{"id":"a53890ea9fcc9069","repo":"vxcontrol/pentagi","slug":"path-is-required-and-cannot-be-empty","errorCode":null,"errorMessage":"path is required and cannot be empty","messagePattern":"path is required and cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/terminal.go","lineNumber":331,"sourceCode":"\n\tresults := dst.String()\n\t// Style system output with color coding\n\tstyledOutput := fmt.Sprintf(\"%s%s%s%s\", ansiColorSystemMsg, results, ansiColorReset, ansiLineTerminator)\n\t_, err = t.tlp.PutMsg(ctx, database.TermlogTypeStdout, styledOutput, t.containerID, t.taskID, t.subtaskID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to put terminal log (stdout): %w\", err)\n\t}\n\n\tif results == \"\" {\n\t\tresults = \"Command completed successfully with exit code 0. No output produced (silent success)\"\n\t}\n\n\treturn results, nil\n}\n\nfunc (t *terminal) ReadFile(ctx context.Context, flowID int64, path string) (string, error) {\n\tif path == \"\" {\n\t\treturn \"\", fmt.Errorf(\"path is required and cannot be empty\")\n\t}\n\n\tcwd := docker.WorkFolderPathInContainer\n\tescapedPath := strings.ReplaceAll(path, \"'\", \"'\\\"'\\\"'\")\n\tcatCommand := fmt.Sprintf(\"cat '%s'\", escapedPath)\n\t// Format read file command with styling\n\tstyledCommand := fmt.Sprintf(\"%s $ %s%s%s%s\", cwd, ansiColorInputCmd, catCommand, ansiColorReset, ansiLineTerminator)\n\t_, err := t.tlp.PutMsg(ctx, database.TermlogTypeStdin, styledCommand, t.containerID, t.taskID, t.subtaskID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to put terminal log (read file cmd): %w\", err)\n\t}\n\n\tcontent, err := t.readFileFromContainer(ctx, flowID, path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Style file content output","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/terminal.go#L313-L349","documentation":"ReadFile validates its input before doing any container work: an empty path cannot name a file inside the container, so the call is rejected immediately with this error. It is a guard against building a meaningless 'cat ''' command.","triggerScenarios":"Calling terminal.ReadFile(ctx, flowID, \"\") — e.g. the caller's path variable was never populated, an upstream tool returned an empty string, or an optional path field was not defaulted.","commonSituations":"LLM agent invokes the read-file tool with a missing/blank path argument; config or task data lacking a file field; string trimming reducing a value to \"\".","solutions":["Provide a valid absolute path inside the container (e.g. /home/user/report.txt)","Validate/trim the path at the call site before invoking ReadFile","If path comes from tool arguments, enforce non-empty in the tool's input schema/validation"],"exampleFix":"// before\ncontent, err := term.ReadFile(ctx, flowID, path) // path == \"\"\n// after\npath = strings.TrimSpace(path)\nif path == \"\" {\n    return errors.New(\"cannot read file: path is empty\")\n}\ncontent, err := term.ReadFile(ctx, flowID, path)","handlingStrategy":"validation","validationCode":"func safeReadFile(ctx context.Context, term Terminal, flowID int64, path string) (string, error) {\n    path = strings.TrimSpace(path)\n    if path == \"\" {\n        return \"\", errors.New(\"path is required\")\n    }\n    return term.ReadFile(ctx, flowID, path)\n}","typeGuard":"func validPath(path string) bool {\n    return strings.TrimSpace(path) != \"\"\n}","tryCatchPattern":"content, err := term.ReadFile(ctx, flowID, path)\nif err != nil && strings.Contains(err.Error(), \"path is required\") {\n    return fmt.Errorf(\"read skipped: %w\", err)\n}","preventionTips":["Validate tool-call arguments at the schema layer (non-empty path)","Trim whitespace before calling ReadFile","Default optional path fields explicitly","Never pass through raw LLM-generated arguments unchecked"],"tags":["validation","input","filesystem"],"backgroundTag":"missing-required-argument","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}