multica-ai/multica · error

state marker is not a regular file: %s

Error message

state marker is not a regular file: %s

What it means

prepareHermesTaskLocalState found the task-local-state marker file inside the overlay, but Lstat says it is not a regular file (a directory, symlink, fifo, etc.). The marker records that state.db has been migrated to task-local storage; a non-regular marker means the overlay is corrupt or was tampered with, and the migration logic cannot trust it.

Source

Thrown at server/internal/daemon/execenv/hermes_home.go:578

		}
		if err := os.RemoveAll(filepath.Join(hermesHome, name)); err != nil {
			return fmt.Errorf("reconcile stale %s: %w", name, err)
		}
	}
	return nil
}

// prepareHermesTaskLocalState migrates an overlay built by an older daemon away
// from the shared Hermes SQLite session store. Without the marker, state.db and
// its sidecars may be symlinks or independently copied files; neither is safe to
// reuse as task-local state. Remove only those entries inside the generated
// overlay, then record the migration atomically. Hermes lazily creates a fresh
// database, and later prepares preserve it because the marker is present.
func prepareHermesTaskLocalState(hermesHome string) error {
	marker := filepath.Join(hermesHome, hermesTaskLocalStateMarker)
	if fi, err := os.Lstat(marker); err == nil {
		if !fi.Mode().IsRegular() {
			return fmt.Errorf("state marker is not a regular file: %s", marker)
		}
		return nil
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("stat state marker: %w", err)
	}

	entries, err := os.ReadDir(hermesHome)
	if err != nil {
		return fmt.Errorf("read overlay home: %w", err)
	}
	for _, entry := range entries {
		if !isHermesTaskLocalStateEntry(entry.Name()) {
			continue
		}
		path := filepath.Join(hermesHome, entry.Name())
		if err := os.RemoveAll(path); err != nil {
			return fmt.Errorf("remove legacy task state %s: %w", path, err)
		}

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Inspect the marker path printed in the error: `ls -la <hermesHome>/<marker>` and remove the non-regular entry.
  2. Simplest fix: delete the whole generated overlay dir — it is rebuilt from the shared home on next prepare.
  3. Keep external tools (backup, sync, editors) away from generated env overlay directories.
  4. After cleanup, rerun the task and confirm prepare succeeds and a fresh regular marker appears.
Defensive patterns

Strategy: validation

Validate before calling

marker := filepath.Join(hermesHome, hermesTaskLocalStateMarker)
if fi, err := os.Lstat(marker); err == nil && !fi.Mode().IsRegular() {
	// corrupt marker: drop the regenerable overlay rather than failing
	if err := os.RemoveAll(hermesHome); err != nil { return err }
}

Try / catch

if err := prepareHermesTaskLocalState(hermesHome); err != nil {
	if strings.Contains(err.Error(), "state marker is not a regular file") {
		_ = os.RemoveAll(hermesHome) // fully regenerable; next prepare rebuilds
		return prepareHermesTaskLocalState(hermesHome)
	}
	return err
}

Prevention

When it happens

Trigger: Something replaced .hermes marker file inside env RootDir/hermes-home with a directory or symlink — manual fiddling with the overlay, a broken restore/sync tool, or an old daemon that created it with a different shape.

Common situations: Users hand-editing the overlay home; backup/restore tools that materialize symlinks for small files; partial rsync of the env dir that turned the marker into something else.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/a7b5a3474e73f472. Report an issue: GitHub.