gofr-dev/gofr · error

failed to create directory %q: %w

Error message

failed to create directory %q: %w

What it means

A single directory level could not be created in the Azure File share, and the error was not the benign 'already exists' case (which isDirectoryExistsError filters out). It occurs during ensureParentDirectories when materializing parent folders for a file write.

Source

Thrown at pkg/gofr/datasource/file/azure/storage_adapter.go:841

	return r.reader.Close()
}

// isDirectoryExistsError checks if the error indicates the directory already exists.
func isDirectoryExistsError(err error) bool {
	errStr := err.Error()

	return strings.Contains(errStr, "already exists") ||
		strings.Contains(errStr, "ShareAlreadyExists") ||
		strings.Contains(errStr, "ResourceAlreadyExists")
}

// createDirectoryLevel creates a single directory level and handles errors.
func (s *storageAdapter) createDirectoryLevel(ctx context.Context, dirPath string) error {
	dirClient := s.shareClient.NewDirectoryClient(dirPath)

	_, err := dirClient.Create(ctx, nil)
	if err != nil && !isDirectoryExistsError(err) {
		return fmt.Errorf("failed to create directory %q: %w", dirPath, err)
	}

	return nil
}

// ensureParentDirectories creates all parent directories for the given file path.
// Azure File Storage requires explicit directory creation for directories to appear in listings.
// This function ensures parent directories are created before file creation, matching
// local filesystem behavior where os.MkdirAll is called automatically.
func (s *storageAdapter) ensureParentDirectories(ctx context.Context, filePath string) error {
	if s.shareClient == nil {
		return errAzureClientNotInitialized
	}

	// Extract parent directory path
	parentDir := getParentDir(filePath)
	if parentDir == "" {
		return nil // File is in root, no parent directories needed

View on GitHub (pinned to 187eb24962)

Solutions

  1. Read the wrapped error's Azure code — ParentNotFound means the parent of this level doesn't exist (ensureParentDirectories should create levels in order; check path splitting).
  2. Sanitize directory names: remove illegal characters (\ / : * ? " < > |), trailing dots/spaces, and reserved device names.
  3. Verify the share exists (create it via shareClient.Create if needed) and credentials allow create.
  4. Check for a file already existing at the same path as the intended directory (Conflict).

Example fix

// before
dirPath := strings.Join(parts, "/") // "a/b" in one level
// after
for _, part := range parts { // create one sanitized level at a time
    part = sanitize(part)
    if err := adapter.createDirectoryLevel(ctx, part); err != nil {
        return err
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

var invalidDirChars = regexp.MustCompile(`[\\/:*?"<>|]`)
func validDirName(name string) bool {
    return name != "" && len(name) <= 255 &&
        !invalidDirChars.MatchString(name) &&
        !strings.HasSuffix(name, ".") && !strings.HasSuffix(name, " ") &&
        !strings.EqualFold(name, "aux")
}

Try / catch

if err := store.Create(ctx, dir + "/file.txt"); err != nil {
    if strings.Contains(err.Error(), "failed to create directory") {
        // sanitize path levels or create share, then retry
    }
    return err
}

Prevention

When it happens

Trigger: Uploading/writing a file whose parent directory path requires creation, and dirClient.Create fails with a real error: invalid directory name (illegal characters, too long, trailing spaces/dots), share missing, or insufficient permissions.

Common situations: Path components containing characters Azure Files rejects (e.g. "dir\\sub", "a/b" embedded in a level, names over 255 chars, reserved names like 'aux'); writing to a share that doesn't exist; SAS without create permission; conflicting file exists at the same path as the directory.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/2e0533f5a7b8c4e9. Report an issue: GitHub.