{"record":{"id":"ee167b83e91c5224","repo":"vxcontrol/pentagi","slug":"file-name-contains-unsupported-characters","errorCode":null,"errorMessage":"file name contains unsupported characters","messagePattern":"file name contains unsupported characters","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"backend/pkg/flowfiles/files.go","lineNumber":171,"sourceCode":"\n\treturn path.Join(parts...), nil\n}\n\nfunc validatePathComponent(component string) (string, error) {\n\tcleanName := strings.TrimSpace(component)\n\tif cleanName == \".\" || cleanName == \"..\" || cleanName == \"/\" || cleanName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"invalid file name\")\n\t}\n\tif len(cleanName) > MaxFileNameLength {\n\t\treturn \"\", fmt.Errorf(\"file name is too long\")\n\t}\n\tfor _, r := range cleanName {\n\t\tif r < 0x20 || r == 0x7f {\n\t\t\treturn \"\", fmt.Errorf(\"file name contains control characters\")\n\t\t}\n\t\tswitch r {\n\t\tcase '/', '\\\\', ':', '*', '?', '\"', '<', '>', '|':\n\t\t\treturn \"\", fmt.Errorf(\"file name contains unsupported characters\")\n\t\t}\n\t}\n\n\treturn cleanName, nil\n}\n\nfunc NewFile(info os.FileInfo, sourceDir string) File {\n\treturn NewFileWithPath(info, path.Join(sourceDir, info.Name()))\n}\n\nfunc NewFileWithPath(info os.FileInfo, filePath string) File {\n\treturn File{\n\t\tID:         ID(filePath),\n\t\tName:       info.Name(),\n\t\tPath:       filePath,\n\t\tSize:       info.Size(),\n\t\tIsDir:      info.IsDir(),\n\t\tModifiedAt: info.ModTime(),","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/flowfiles/files.go#L153-L189","documentation":"validatePathComponent rejects components containing characters that are illegal or dangerous across major filesystems — '/', '\\\\', ':', '*', '?', '\"', '<', '>', '|' — returning 'file name contains unsupported characters'. Since '/' and '\\\\' are path separators (already split upstream), this mostly catches Windows-reserved and glob characters inside a single segment.","triggerScenarios":"SanitizeFileName or SanitizeContainerCachePath with a component containing ':' (e.g. \"C:file\", time stamps like \"12:30.log\"), '*', '?', '\"', '<', '>', or '|' (e.g. glob patterns \"*.log\", pipes \"a|b\").","commonSituations":"Windows-derived names with drive letters or Alternate Data Streams; agent-generated glob patterns like 'reports/*.pdf' passed as a literal file name; timestamps with colons in file names; shell redirection characters copied into names.","solutions":["Replace the unsupported characters (e.g. ':' → '-', '*' → '_') before calling.","Pass glob patterns through the appropriate listing/search API instead of as literal file names.","Sanitize timestamps by formatting without colons (e.g. 12-30-00 instead of 12:30:00)."],"exampleFix":"// before\nname, err := flowfiles.SanitizeFileName(\"backup_12:30:00.tar\")\n// after\nname, err := flowfiles.SanitizeFileName(strings.ReplaceAll(\"backup_12:30:00.tar\", \":\", \"-\"))","handlingStrategy":"validation","validationCode":"var unsupported = \"/:*?\\\"<>|\\\\\"\nfunc hasUnsupportedChars(s string) bool {\n    return strings.ContainsAny(s, unsupported)\n}","typeGuard":"func isPortableName(s string) bool {\n    return !strings.ContainsAny(s, \"/:*?\\\"<>|\\\\\")\n}","tryCatchPattern":"if err != nil {\n    if err.Error() == \"file name contains unsupported characters\" {\n        return fmt.Errorf(\"replace : * ? \\\" < > | in the file name before upload\")\n    }\n    return err\n}","preventionTips":["Format timestamps without colons in file names.","Never pass glob patterns as literal file names.","Strip Windows drive letters and reserved characters cross-platform."],"tags":["go","filename-validation","input-validation"],"backgroundTag":"invalid-filename-characters","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}