dagger/dagger · error
%q is not a directory
Error message
%q is not a directory
What it means
newWorkdir validates that the resolved workdir root (from --workdir or cwd) is an existing directory before initializing the interactive shell's filesystem view. If os.Stat succeeds but the target is a regular file (or other non-directory), Dagger returns this error instead of starting the shell. It guards the shell against operating on paths it cannot traverse as a directory tree.
Source
Thrown at internal/cmd/dagger/shell_fs.go:433
h.mu.RLock()
context = h.wd.Context
digest = h.wd.Module
h.mu.RUnlock()
}
// initial context, without a loaded module (core API only)
if context == nil {
// a few quick checks first
root, err := pathutil.Abs(subpath)
if err != nil {
return nil, err
}
info, err := os.Stat(root)
if err != nil {
return nil, err
}
if !info.IsDir() {
return nil, fmt.Errorf("%q is not a directory", root)
}
if !h.noModule {
// ask API where the context dir is (.git)
ctx, span := Tracer().Start(ctx, "looking for context directory", telemetry.Internal())
defer telemetry.EndWithCause(span, &rerr)
src := h.dag.ModuleSource(root, dagger.ModuleSourceOpts{
DisableFindUp: true,
AllowNotExists: true,
})
root, err = src.LocalContextDirectoryPath(ctx)
if err != nil {
return nil, err
}
subpath, err = src.SourceRootSubpath(ctx)
if err != nil {
return nil, errView on GitHub (pinned to 82ba2681db)
Solutions
- Pass a directory path to --workdir (or run from a directory), not a file
- Verify with 'ls -la <path>' or 'os.Stat' that the target is a directory
- If a symlink is involved, confirm it resolves to a directory
- Update the calling script (Initialize/ChangeDir input) to strip the filename component
Example fix
// before dagger --workdir ./config.yaml // after dagger --workdir .
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(root)
if err != nil { return err }
if !info.IsDir() { return fmt.Errorf("%q is not a directory", root) }
// only then: dagger --workdir root Try / catch
if err := runDaggerShell(); err != nil {
if strings.Contains(err.Error(), "is not a directory") {
// fix workdir path and retry
}
} Prevention
- Validate workdir with os.Stat/IsDir before launching the shell
- Don't pass file paths as --workdir
- Resolve symlinks and confirm target kind
- Use filepath.Dir() when a path may include a filename
When it happens
Trigger: Running 'dagger' shell / 'dagger terminal'-style init with --workdir pointing to a file (e.g. --workdir ./dagger.config.ts), or when the cwd path resolves to a file; also reached via ChangeDir into a non-directory path.
Common situations: Typo where a filename is passed instead of its parent directory; a symlink resolving to a file; scripts that compute the workdir path and accidentally append a filename; workdir deleted and replaced by a file.
Related errors
- change workdir: %w
- get workdir: %w
- working dir %s points to invalid target: %w
- couldn't write output to file: %w
- create profile: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/293e6cd099a43c4d.
Report an issue: GitHub.