Skip to content

TBEventFileCollectionIterator opens every dir entry, crashing on Windows when logdir contains subdirectories #152

Description

@CarloLucibello

TBEventFileCollectionIterator(path) (used by map_summaries / read_* helpers) calls open on every entry returned by readdir, including subdirectories. Opening a directory works on Linux/macOS but throws SystemError: Permission denied on Windows, so reading a log directory that contains any subdirectory fails on Windows.

Location

src/Deserialization/deserialization.jl:

function TBEventFileCollectionIterator(path; purge=true)
    fnames = sort(readdir(path))
    good_fnames = typeof(fnames)()

    for fname in fnames
        open(joinpath(path,fname), "r") do f   # <-- also runs on subdirectories
            is_valid_event(f) && push!(good_fnames, fname)
        end
    end
    ...

Reproduction

Create a TBLogger, then add any subdirectory next to the event files (a common real-world case: a checkpoints/ folder saved alongside the logs), and read the logs back:

using TensorBoardLogger, Logging
dir = mktempdir()
lg = TBLogger(dir)
with_logger(lg) do
    @info "scalar" value = 1.0
end
mkdir(joinpath(dir, "checkpoints"))   # any sibling subdirectory

map_summaries((args...) -> nothing, dir)

On Windows this throws:

SystemError: opening file "...\checkpoints": Permission denied

On Linux/macOS open on a directory happens to succeed and is_valid_event returns false, so the entry is silently skipped — which is why the bug is invisible outside Windows.

Suggested fix

Skip non-files before opening, e.g.:

for fname in fnames
    isfile(joinpath(path, fname)) || continue
    open(joinpath(path, fname), "r") do f
        is_valid_event(f) && push!(good_fnames, fname)
    end
end

This also makes the "we ignore other files in this folder" comment hold for subdirectories, and is a no-op on the platforms where it currently happens to work.

Environment

Happy to open a PR with the one-line isfile guard if that's welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions