{"record":{"id":"cf0b5bb1f91b3d73","repo":"temporalio/temporal","slug":"failed-to-parse-visibility-filename-s","errorCode":null,"errorMessage":"failed to parse visibility filename %s","messagePattern":"failed to parse visibility filename (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/archiver/filestore/visibility_archiver.go","lineNumber":262,"sourceCode":"\treturn validateDirPath((URI.Path()))\n}\n\ntype parsedVisFilename struct {\n\tname        string\n\tcloseTime   time.Time\n\thashedRunID string\n}\n\n// sortAndFilterFiles sort visibility record file names based on close timestamp (desc) and use hashed runID to break ties.\n// if a nextPageToken is give, it only returns filenames that have a smaller close timestamp\nfunc sortAndFilterFiles(filenames []string, token *queryVisibilityToken) ([]string, error) {\n\tvar parsedFilenames []*parsedVisFilename\n\tfor _, name := range filenames {\n\t\tpieces := strings.FieldsFunc(name, func(r rune) bool {\n\t\t\treturn r == '_' || r == '.'\n\t\t})\n\t\tif len(pieces) != 3 {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse visibility filename %s\", name)\n\t\t}\n\n\t\tcloseTime, err := strconv.ParseInt(pieces[0], 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse visibility filename %s\", name)\n\t\t}\n\t\tparsedFilenames = append(parsedFilenames, &parsedVisFilename{\n\t\t\tname:        name,\n\t\t\tcloseTime:   timestamp.UnixOrZeroTime(closeTime),\n\t\t\thashedRunID: pieces[1],\n\t\t})\n\t}\n\n\tsort.Slice(parsedFilenames, func(i, j int) bool {\n\t\tif parsedFilenames[i].closeTime.Equal(parsedFilenames[j].closeTime) {\n\t\t\treturn parsedFilenames[i].hashedRunID > parsedFilenames[j].hashedRunID\n\t\t}\n\t\treturn parsedFilenames[i].closeTime.After(parsedFilenames[j].closeTime)","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/archiver/filestore/visibility_archiver.go#L244-L280","documentation":"sortAndFilterFiles in the filestore visibility archiver parses archived visibility record filenames of the form <closeTime>_<hashedRunID>_<ext>, splitting on '_' and '.' and requiring exactly 3 pieces. If a filename does not split into 3 fields, it returns 'failed to parse visibility filename %s'. This guards against foreign or corrupted files in the archive directory.","triggerScenarios":"Querying the file-based visibility archiver when the archive directory contains a file whose name does not have exactly two underscores and one dot-separated extension segment (e.g. 'run_failed.txt' or a manually placed file).","commonSituations":"Operators placing logs, temp files, or backups into the archive directory; a different archiver format version writing different filenames; or partial writes leaving truncated names.","solutions":["Remove or move out the non-conforming file from the visibility archive directory","Rename the file to the canonical '<closeTimeUnixNano>_<hashedRunID>_<ext>' format if its data is valid","Verify all files in the directory were written by the same archiver version/format"],"exampleFix":"// before\narchive dir: 1727123456789012345_a1b2c3_visibility\nnotes.txt   <- stray file\n// after\nmv notes.txt /var/log/archive-notes/  # keep archive dir only for visibility files","handlingStrategy":"validation","validationCode":"for _, name := range filenames {\n  if len(strings.FieldsFunc(name, func(r rune) bool { return r == '_' || r == '.' })) != 3 {\n    // clean or quarantine before querying\n  }\n}","typeGuard":"func isValidVisFilename(name string) bool { return len(strings.FieldsFunc(name, func(r rune) bool { return r == '_' || r == '.' })) == 3 }","tryCatchPattern":"resp, err := client.ArchiveQuery(ctx, req)\nif err != nil {\n  if strings.Contains(err.Error(), \"failed to parse visibility filename\") {\n    logger.Warn(\"archive dir contains foreign file\", tag.Error(err))\n  }\n  return err\n}","preventionTips":["Keep the archive directory dedicated to visibility files — no manual drops","Monitor the archive directory for unexpected files","Keep the archiver version uniform; don't mix filename formats"],"tags":["go","archiver","filestore","visibility"],"backgroundTag":"invalid-filename-format","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}