{"record":{"id":"b99f18051cd2b255","repo":"vxcontrol/pentagi","slug":"path-is-required","errorCode":null,"errorMessage":"path is required","messagePattern":"path is required","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"backend/pkg/flowfiles/files.go","lineNumber":136,"sourceCode":"\treturn absPath, nil\n}\n\nfunc SanitizeFileName(fileName string) (string, error) {\n\ttrimmedName := strings.TrimSpace(fileName)\n\tif trimmedName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"file name is required\")\n\t}\n\n\tnormalizedName := strings.ReplaceAll(trimmedName, \"\\\\\", \"/\")\n\tcleanName := path.Base(path.Clean(\"/\" + normalizedName))\n\n\treturn validatePathComponent(cleanName)\n}\n\nfunc SanitizeContainerCachePath(containerPath string) (string, error) {\n\ttrimmedPath := strings.TrimSpace(containerPath)\n\tif trimmedPath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"path is required\")\n\t}\n\n\tnormalizedPath := strings.ReplaceAll(trimmedPath, \"\\\\\", \"/\")\n\tcleanPath := strings.TrimPrefix(path.Clean(\"/\"+normalizedPath), \"/\")\n\tif cleanPath == \".\" || cleanPath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"invalid path\")\n\t}\n\n\tparts := strings.Split(cleanPath, \"/\")\n\tfor i, part := range parts {\n\t\tcleanPart, err := validatePathComponent(part)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"invalid path component '%s': %w\", part, err)\n\t\t}\n\t\tparts[i] = cleanPart\n\t}\n\n\treturn path.Join(parts...), nil","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/flowfiles/files.go#L118-L154","documentation":"SanitizeContainerCachePath validates a container-side path before it is used in the flow-files cache. It rejects a containerPath that is empty or contains only whitespace, returning 'path is required' because there is nothing to sanitize or store. The function requires a non-empty relative path naming at least one real component.","triggerScenarios":"Calling flowfiles.SanitizeContainerCachePath(\"\") or with a whitespace-only string such as \"   \", typically when the caller received an empty path from an LLM tool call argument, a JSON field that was never set, or a container command output that was empty.","commonSituations":"An agent tool call (e.g. pull_flow_files) passes an unset path argument; a GraphQL/REST client omits the path field; a script building the pull request reads an empty environment variable or empty file listing entry.","solutions":["Provide a non-empty, non-whitespace relative path as the containerPath argument (e.g. \"/tmp/report.pdf\" or \"logs/app.log\").","Trim/default the value at the call site before invoking SanitizeContainerCachePath, and skip entries whose trimmed value is empty.","Log the upstream source of the path (tool call arguments, API request body) and fix whatever produced the empty value."],"exampleFix":"// before\nsanitized, err := flowfiles.SanitizeContainerCachePath(req.ContainerPath)\n// after\nif strings.TrimSpace(req.ContainerPath) == \"\" {\n    return fmt.Errorf(\"container path is required for pull\")\n}\nsanitized, err := flowfiles.SanitizeContainerCachePath(req.ContainerPath)","handlingStrategy":"validation","validationCode":"func requireContainerPath(p string) error {\n    if strings.TrimSpace(p) == \"\" {\n        return errors.New(\"container path must be a non-empty string\")\n    }\n    return nil\n}","typeGuard":"func hasContainerPath(p string) bool {\n    return strings.TrimSpace(p) != \"\"\n}","tryCatchPattern":"if err != nil {\n    if err.Error() == \"path is required\" {\n        return fmt.Errorf(\"caller must supply a container path: %w\", err)\n    }\n    return err\n}","preventionTips":["Default empty tool-call path arguments to an error before reaching the sanitizer.","Trim and validate user/agent input at the API boundary.","Log tool call arguments so empty-path sources are traceable."],"tags":["go","path-validation","input-validation"],"backgroundTag":"empty-path-argument","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}