kataras/iris · error

HandleDir: no directories found under the embedded file syst

Error message

HandleDir: no directories found under the embedded file system

What it means

When HandleDir (via its internal file system resolution) is given an embed.FS, Iris reads the root directory of the embedded FS and, if it is empty (no directories/files embedded), panics because it cannot locate a sub-filesystem to serve. This catches the common mistake of embedding with patterns that match nothing.

Source

Thrown at context/fs.go:118

//
// It affects the Application's API Builder's `HandleDir` method.
//
// This package-level variable can be modified on initialization.
var ResolveHTTPFS = func(fsOrDir any) http.FileSystem {
	var fileSystem http.FileSystem
	switch v := fsOrDir.(type) {
	case string:
		fileSystem = http.Dir(v)
	case http.FileSystem:
		fileSystem = v
	case embed.FS:
		direEtries, err := v.ReadDir(".")
		if err != nil {
			panic(err)
		}

		if len(direEtries) == 0 {
			panic("HandleDir: no directories found under the embedded file system")
		}

		subfs, err := fs.Sub(v, direEtries[0].Name())
		if err != nil {
			panic(err)
		}
		fileSystem = http.FS(subfs)
	case fs.FS:
		fileSystem = http.FS(v)
	default:
		panic(fmt.Sprintf(`unexpected "fsOrDir" argument type of %T (string or http.FileSystem or embed.FS or fs.FS)`, v))
	}

	return fileSystem
}

// FindNames accepts a "http.FileSystem" and a root name and returns
// the list containing its file names.

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Fix the //go:embed pattern so it actually includes the directory's files (e.g. //go:embed public/* and rebuild).
  2. Verify the embedded variable references the correct directory and that the build embeds files (check go build output).
  3. Alternatively pass the embedded sub-directory via embed.FS with fs.Sub semantics handled by the library, or serve an os directory instead.

Example fix

// before
//go:embed public
var assetsFS embed.FS // pattern matched nothing -> empty FS
// after
//go:embed public/*
var assetsFS embed.FS
app.HandleDir("/", assetsFS)
Defensive patterns

Strategy: validation

Validate before calling

entries, err := assetsFS.ReadDir(".")
if err != nil || len(entries) == 0 {
  log.Fatal("embedded FS is empty; check //go:embed pattern")
}
app.HandleDir("/", assetsFS)

Type guard

func embeddedFSEmpty(v embed.FS) bool {
  entries, err := v.ReadDir(".")
  return err != nil || len(entries) == 0
}

Prevention

When it happens

Trigger: Passing an embed.FS to HandleDir (or the fs-resolution helper) where //go:embed matched zero entries, so ReadDir(".") on the embedded FS returns an empty list.

Common situations: //go:embed directive pointing at a path that doesn't exist at build time, embed pattern excluded by .gitignore-like rules, embedding an empty placeholder directory without files.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/e09243a3474575d0. Report an issue: GitHub.