fix: return clear error when COMPOSE_FILE points to a directory#13675
fix: return clear error when COMPOSE_FILE points to a directory#13675m-alikhizar wants to merge 1 commit intodocker:mainfrom
Conversation
When COMPOSE_FILE is set to an empty string or a path that resolves to
a directory (e.g. COMPOSE_FILE="" resolves to cwd via filepath.Abs),
the previous behaviour was to emit a cryptic OS-level error:
read <path>: is a directory
This occurs because compose-go's ReadConfigFiles calls os.ReadFile on
the resolved path, which fails with EISDIR when the path is a directory.
Add an explicit pre-check in both LoadProject (pkg/compose) and ToModel
(cmd/compose) that detects when a resolved config path is a directory
and returns a user-friendly message:
path "<path>" is a directory, not a Compose file;
check the COMPOSE_FILE environment variable or the -f flag
Remote paths (git/OCI) and stdin ("-") are excluded from the check.
Fixes docker#13649
Made-with: Cursor
Signed-off-by: m-alikhizar <m.alikhizar@outlook.com>
Made-with: Cursor
2164493 to
736906f
Compare
glours
left a comment
There was a problem hiding this comment.
Thanks for contributing this fix!
However, I'm not sure this PR addresses the root cause described in the issue. According to the bug report, the misleading error read : is a directory occurs when the user has no permission to access the Docker socket. In that case, the connection to the Docker daemon fails, which seems to cause ConfigPaths to resolve to the current working directory as a fallback — and that's what triggers the confusing message.
The fix improves the error message for the directory case, but it points the user toward checking COMPOSE_FILE or the -f flag, which is not the actual problem here. Someone hitting this scenario would still be confused.
Could you investigate where the socket permission error is swallowed and make sure it surfaces directly instead? That would properly address the issue as reported.
What does this PR fix?
Fixes #13649
When
COMPOSE_FILEis set to an empty string (or any value that resolves to a directory viafilepath.Abs), runningdocker compose up -dproduces the cryptic OS-level error:This happens because
compose-go'sReadConfigFilescallsos.ReadFileon the resolved path, which returnsEISDIRwhen the path is a directory. The error surfaced as a raw syscall message with no guidance for the user.What changed?
Added an explicit pre-check in two places that are responsible for loading project config:
pkg/compose/loader.go– inLoadProject, before delegating tocompose-gocmd/compose/compose.go– inToModel, used by commands likedocker compose configThe check iterates the resolved
ConfigPathsand, for any path that is not stdin (-) or a remote resource (git/OCI), verifies it is not a directory. If it is, a clear actionable error is returned:Testing
TestLoadProject_DirectoryAsComposeFileinpkg/compose/loader_test.gothat:read <path>: is a directorymessage is not presentTestLoadProject_*tests continue to passgolangci-lint v2.11.3(project-pinned version) – 0 issuesBefore / After
COMPOSE_FILE=""in empty dirread /path/to/dir: is a directorypath "/path/to/dir" is a directory, not a Compose file; check the COMPOSE_FILE environment variable or the -f flagdocker compose -f /some/dir upno configuration file provided: not found