Repository: gruntwork-io/terragrunt

Issue:
error with no_dot_terragrunt_stack attribute
## Describe the bug

When "no_dot_terragrunt_stack attribute" is set to true in the terragrunt.stack.hcl and plan/apply fails with message "ERROR  failed to get evaluate sym links for ./.terragrunt-stack: lstat ./.terragrunt-stack: no such file or directory" error.


## Steps To Reproduce

1. Create a new folder called "newstack" and copy below terragrunt.stack.hcl there.
2. Create a folder called "units/s3" and copy terragrunt.hcl there. 
3. Go to units/s3 and run "terragrunt init" and "terragrunt apply".  Bucket should be created.
4. Go to "newstack" folder and run, "terragrunt stack generate".  It should create a folder "mys3" and no .terragrunt-stack folder is created. (expected.)
5. Run "terragrunt stack run plan" and you should see the error.
6. Expected behavior is not to get the error because no_dot_terragrunt_stack is set to true. 

```hcl
unit "mys3" {

  source = "./units/s3"
  path = "mys3"

  values = {
    bucket_name = "mybucket-028232323710"

    tag_owner   = "Tag owner tbd"
    tag_purpose = "demo"
    tag_details = "details tbd"
    }
    no_dot_terragrunt_stack = true
}
```

```hcl
include "root" {
  path = find_in_parent_folders("root.hcl")
}

terraform {
  source = "file:///data/terragrunt/modules/s3"
  #source = "git::https://github.com/rshettynj/terragrunt-demo-modules.git//s3?ref=master"
}

inputs = {

  /*
  bucket_name = values.bucket_name

  tag_owner   = values.tag_owner
  tag_purpose = values.tag_purpose
  tag_details = values.tag_details
  */
  bucket_name = "random-823732732237"

  tag_owner   = "owner NA"
  tag_purpose = "purpose NA"
  tag_details = "details NA"
}
```

## Expected behavior

I expect the terragrunt apply to run without the error. Stack should have seen no_dot_terragrunt_stack set to true and bypass the .terragrunt-stack folder.

## Nice to haves

[root@ip-172-30-2-182 newstack]# terragrunt stack run plan
15:39:57.197 INFO   Generating stack from ./terragrunt.stack.hcl
15:39:57.216 INFO   Processing unit mys3
15:40:16.203 ERROR  failed to get evaluate sym links for ./.terragrunt-stack: lstat ./.terragrunt-stack: no such file or directory
15:40:16.207 ERROR  Unable to determine underlying exit code, so Terragrunt will exit with error code 1


## Versions

- Terragrunt version:terragrunt version v0.77.20
- OpenTofu/Terraform version:
- Terraform v1.11.4
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v5.95.0

- Environment details (Ubuntu 20.04, Windows 10, etc.):

## Additional context

When is one more unit added in the stack and no_dot_terragrunt_stack is false (not set), I have observed there is no error.
This makes me suspect this is a bug.


Discussion:
@Mjb141: I'm getting this.

Unit with `no_dot_terragrunt_stack` results in `lstat <path>: no such file or directory`

Same unit, same path, executing terragrunt from the same dir (repository root) without `no_dot_terragrunt_stack` results in a plan but 48 to create, 0 to change, 0 to delete (because backend has `key = "${path_relative_to_include()}/terraform.tfstate"` and the path has obviously changed.

My `terragrunt.stack.hcl` has one `unit` block.@pomverte: My workaround:
```
terragrunt stack generate
terragrunt run --all plan
```@Mjb141: > My workaround:
> 
> ```
> terragrunt stack generate
> terragrunt run --all plan
> ```

This does not work for me - still has issues with relative paths.@dlane-cbts: I am seeing this error with both ` no_dot_terragrunt_stack = true/false`

```
14:54:41.831 INFO   Processing unit wlz_shared
14:54:41.831 DEBUG  Processing: wlz_shared (../../../terraform//wlz_shared) to ./prd/shared
14:54:41.855 DEBUG  Skipping validation for unit wlz_shared due to no_stack flag
14:54:41.855 DEBUG  Writing values file in ./prd/shared
14:54:41.856 DEBUG  Searching for stack files in .
14:54:41.864 DEBUG  Found stack file ./dev/terragrunt.stack.hcl
14:54:41.872 DEBUG  Found stack file ./prd/terragrunt.stack.hcl
14:54:41.874 ERROR  failed to get evaluate sym links for ./.terragrunt-stack: lstat ./.terragrunt-stack: no such file or directory
14:54:41.875 ERROR  Unable to determine underlying exit code, so Terragrunt will exit with error code 1
```

Stacks are created in the correct folders

`terragrunt.stack.hcl`

```
locals {
  env                   = "dev"
  app                   = "shared"
  location              = "Central US"
}

unit "wlz_shared" {
  source = "${get_repo_root()}/terraform//wlz_shared"
  path = "shared"

  values = {
    deployment  = {
      app            = local.app
      env            = local.env
      location       = local.location
      deploy_storage = false
    }
  }
   no_dot_terragrunt_stack = true
}
```
`terragrunt.hcl`

```
include "root" {
  path = find_in_parent_folders("root.hcl")
}

terraform {
  source = "${get_repo_root()}/terraform//wlz_shared"
 }

inputs = {
  deployment = values.deployment
}
```

```
terragrunt version v0.78.4
Ubuntu 22.04.4 LTS
```@alandreasyans: It would make sense to add functionality to automatically plan/apply from the specific folder if the no_dot_terragrunt_stack = true. 
Now I could find the stacks useful only for the terragrunt.hcl files generation as the rest are the same commands.@denis256: If `.terragrunt-stack` isn't created (e.g., all units have `no_dot_terragrunt_stack = true` and nothing needs to be copied), then `stack run / output` won't work.
In this case, use `terragrunt run` commands directly in the directory.
@dlane-cbts: > If `.terragrunt-stack` isn't created (e.g., all units have `no_dot_terragrunt_stack = true` and nothing needs to be copied), then `stack run / output` won't work. In this case, use `terragrunt run` commands directly in the directory.

I have set specifically `no_dot_terragrunt_stack = false` just to make sure, I still see the `symlink` error

```
$:.../wlz_datalake$ terragrunt stack run plan
14:17:34.116 INFO   Generating stack from ./dev/terragrunt.stack.hcl
14:17:34.135 INFO   Generating stack from ./prd/terragrunt.stack.hcl
14:17:34.135 INFO   Processing unit wlz_datalake from ./dev/terragrunt.stack.hcl
14:17:34.163 INFO   Processing unit wlz_datalake from ./prd/terragrunt.stack.hcl
14:17:34.261 ERROR  failed to get evaluate sym links for ./.terragrunt-stack: lstat ./.terragrunt-stack: no such file or directory
14:17:34.261 ERROR  Unable to determine underlying exit code, so Terragrunt will exit with error code 1
14:17:34.261 ERROR  failed to get evaluate sym links for ./.terragrunt-stack: lstat ./.terragrunt-stack: no such file or directory
14:17:34.261 ERROR  Unable to determine underlying exit code, so Terragrunt will exit with error code 1
```

I do show that `.terragrunt-stack` folders are created and templated correctly @idkman23: In the current version the error message has changed to `Stack directory does not exist or is not accessible: ./.terragrunt-stack`

Solution patch:
diff --git a/.github/ISSUE_TEMPLATE/02-bad_error_message.md b/.github/ISSUE_TEMPLATE/02-bad_error_message.md
new file mode 100644
index 00000000..78809e73
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/02-bad_error_message.md
@@ -0,0 +1,58 @@
+---
+name: Bad Error Message Report
+about: Report an error message that is unclear, unhelpful, or confusing to users.
+title: ''
+labels:
+  - bug
+  - error-message
+assignees: ''
+
+---
+
+## Error Message Details
+
+### The Error Message
+
+Please paste the exact error message you received:
+
+```bash
+// Paste the complete error message here
+```
+
+## Why This Error Message is Unhelpful
+
+### Current Problems
+
+Please explain why this error message is not helpful.
+
+## Recommended Improvement
+
+### What the Error Message Should Say
+
+Please suggest how the error message could be improved:
+
+```bash
+// Example of what a better error message might look like
+```
+
+## Error Reproduction Steps
+
+Provide the exact steps required for _anyone_ to successfully reproduce the error.
+
+This includes the Terragrunt command and any relevant configuration files required to reproduce the error. If you need a large amount of Terragrunt configuration to reproduce the error, consider creating a minimal reproduction repository.
+
+### Steps to Reproduce
+
+1.
+2.
+3.
+
+## Environment Information
+
+- **Terragrunt version**:
+- **OpenTofu/Terraform version**:
+- **Operating system**:
+
+## Additional Context
+
+Any other information that might help improve the error message.
diff --git a/.github/ISSUE_TEMPLATE/02-rfc.yml b/.github/ISSUE_TEMPLATE/03-rfc.yml
similarity index 100%
rename from .github/ISSUE_TEMPLATE/02-rfc.yml
rename to .github/ISSUE_TEMPLATE/03-rfc.yml
diff --git a/.github/ISSUE_TEMPLATE/03-feature-request.md b/.github/ISSUE_TEMPLATE/04-feature-request.md
similarity index 100%
rename from .github/ISSUE_TEMPLATE/03-feature-request.md
rename to .github/ISSUE_TEMPLATE/04-feature-request.md
diff --git a/.github/ISSUE_TEMPLATE/04-iac-engine-bug-report.md b/.github/ISSUE_TEMPLATE/04-iac-engine-bug-report.md
deleted file mode 100644
index 6541c1a7..00000000
--- a/.github/ISSUE_TEMPLATE/04-iac-engine-bug-report.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-name: IaC Engine Bug Report
-about: Report a bug in the IaC Engine.
-title: ''
-labels: bug, iac-engine
-assignees: ''
-
----
-
-## Describe the bug
-
-A clear and concise description of what the bug is.
-
-## Steps To Reproduce
-
-Steps to reproduce the behavior, code snippets and examples which can be used to reproduce the issue.
-
-Be sure that the maintainers can actually reproduce the issue. Bug reports that are too vague or hard to reproduce are hard to troubleshoot and fix.
-
-```hcl
-// paste code snippets here
-```
-
-## Expected behavior
-
-A clear and concise description of what you expected to happen.
-
-## Nice to haves
-
-- [ ] Terminal output
-- [ ] Screenshots
-
-## Versions
-
-- Terragrunt version:
-- Engine source:
-- Engine version:
-- OpenTofu/Terraform version:
-- Environment details (Ubuntu 20.04, Windows 10, etc.):
-
-## Additional context
-
-Add any other context about the problem here.
-
diff --git a/.github/workflows/strict-lint.yml b/.github/workflows/strict-lint.yml
deleted file mode 100644
index 8db5ccb2..00000000
--- a/.github/workflows/strict-lint.yml
+++ /dev/null
@@ -1,49 +0,0 @@
-name: Strict Lint
-
-on:
-  push:
-
-jobs:
-  lint:
-    runs-on: ubuntu-latest
-
-    steps:
-    - uses: actions/checkout@v4
-
-    - name: Set up mise
-      uses: jdx/mise-action@v2
-      with:
-        version: 2025.4.4
-        experimental: true
-      env:
-        # Adding token here to reduce the likelihood of hitting rate limit issues.
-        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
-    - id: go-cache-paths
-      run: |
-        echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
-        echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
-
-        # TODO: Make this less brittle.
-        echo "golanci-lint-cache=/home/runner/.cache/golangci-lint" >> "$GITHUB_OUTPUT"
-
-    - name: Go Build Cache
-      uses: actions/cache@v4
-      with:
-        path: ${{ steps.go-cache-paths.outputs.go-build }}
-        key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-linux-amd64
-
-    - name: Go Mod Cache
-      uses: actions/cache@v4
-      with:
-        path: ${{ steps.go-cache-paths.outputs.go-mod }}
-        key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-linux-amd64
-
-    - name: golangci-lint Cache
-      uses: actions/cache@v4
-      with:
-        path: ${{ steps.go-cache-paths.outputs.golanci-lint-cache }}
-        key: ${{ runner.os }}-golangci-lint-${{ hashFiles('**/go.sum') }}-linux-amd64
-
-    - name: Strict Lint
-      run: make run-strict-lint
diff --git a/cli/commands/stack/stack.go b/cli/commands/stack/stack.go
index 65fae204..526ee601 100644
--- a/cli/commands/stack/stack.go
+++ b/cli/commands/stack/stack.go
@@ -2,7 +2,6 @@ package stack
 
 import (
 	"context"
-	"os"
 	"path/filepath"
 	"strings"
 
@@ -17,10 +16,6 @@ import (
 	"github.com/gruntwork-io/terragrunt/options"
 )
 
-const (
-	stackDir = ".terragrunt-stack"
-)
-
 // RunGenerate runs the stack command.
 func RunGenerate(ctx context.Context, l log.Logger, opts *options.TerragruntOptions) error {
 	opts.TerragruntStackConfigPath = filepath.Join(opts.WorkingDir, config.DefaultStackFile)
@@ -70,11 +65,6 @@ func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOptions) err
 		return err
 	}
 
-	opts.WorkingDir = filepath.Join(opts.WorkingDir, stackDir)
-	if _, err := os.Stat(opts.WorkingDir); os.IsNotExist(err) {
-		return errors.Errorf("Stack directory does not exist or is not accessible: %s", opts.WorkingDir)
-	}
-
 	return runall.Run(ctx, l, opts)
 }
 
diff --git a/config/config.go b/config/config.go
index 9a429ddf..90ace31e 100644
--- a/config/config.go
+++ b/config/config.go
@@ -1896,6 +1896,10 @@ func validateGenerateBlocks(blocks *[]terragruntGenerateBlock) error {
 func configFileHasDependencyBlock(configPath string) (bool, error) {
 	configBytes, err := os.ReadFile(configPath)
 	if err != nil {
+		if os.IsNotExist(err) {
+			return false, DependencyFileNotFoundError{Path: configPath}
+		}
+
 		return false, errors.New(err)
 	}
 
diff --git a/config/config_partial.go b/config/config_partial.go
index 87c955d5..c237c102 100644
--- a/config/config_partial.go
+++ b/config/config_partial.go
@@ -705,12 +705,23 @@ func partialParseIncludedConfig(ctx *ParsingContext, l log.Logger, includedConfi
 		includePath = util.JoinPath(filepath.Dir(ctx.TerragruntOptions.TerragruntConfigPath), includePath)
 	}
 
-	return PartialParseConfigFile(
+	config, err := PartialParseConfigFile(
 		ctx,
 		l,
 		includePath,
 		includedConfig,
 	)
+	if err != nil {
+		// Convert generic config not found error to include-specific error
+		var configNotFoundError TerragruntConfigNotFoundError
+		if errors.As(err, &configNotFoundError) {
+			return nil, IncludeConfigNotFoundError{IncludePath: includePath, SourcePath: ctx.TerragruntOptions.TerragruntConfigPath}
+		}
+
+		return nil, err
+	}
+
+	return config, nil
 }
 
 // This decodes only the `include` blocks of a terragrunt config, so its value can be used while decoding the rest of
diff --git a/config/errors.go b/config/errors.go
index d61e0d51..e7542a28 100644
--- a/config/errors.go
+++ b/config/errors.go
@@ -19,6 +19,15 @@ func (err IncludedConfigMissingPathError) Error() string {
 	return fmt.Sprintf("The include configuration in %s must specify a 'path' parameter", string(err))
 }
 
+type IncludeConfigNotFoundError struct {
+	IncludePath string
+	SourcePath  string
+}
+
+func (err IncludeConfigNotFoundError) Error() string {
+	return fmt.Sprintf("Include configuration not found: %s (referenced from: %s)", err.IncludePath, err.SourcePath)
+}
+
 type TooManyLevelsOfInheritanceError struct {
 	ConfigPath             string
 	FirstLevelIncludePath  string
@@ -188,6 +197,14 @@ func (err InvalidIncludeKeyError) Error() string {
 	return fmt.Sprintf("There is no include block in the current config with the label '%s'", err.name)
 }
 
+type DependencyFileNotFoundError struct {
+	Path string
+}
+
+func (err DependencyFileNotFoundError) Error() string {
+	return "Dependency file not found: " + err.Path
+}
+
 // Dependency Custom error types
 
 type DependencyConfigNotFound struct {
diff --git a/config/include.go b/config/include.go
index 6f62c6e5..4c7cbad1 100644
--- a/config/include.go
+++ b/config/include.go
@@ -95,7 +95,20 @@ func parseIncludedConfig(ctx *ParsingContext, l log.Logger, includedConfig *Incl
 		return PartialParseConfigFile(ctx, l, includePath, includedConfig)
 	}
 
-	return ParseConfigFile(ctx, l, includePath, includedConfig)
+	config, err := ParseConfigFile(ctx, l, includePath, includedConfig)
+	if err != nil {
+		var configNotFoundError TerragruntConfigNotFoundError
+		if errors.As(err, &configNotFoundError) {
+			return nil, IncludeConfigNotFoundError{
+				IncludePath: includePath,
+				SourcePath:  ctx.TerragruntOptions.TerragruntConfigPath,
+			}
+		}
+
+		return nil, err
+	}
+
+	return config, nil
 }
 
 // handleInclude merges the included config into the current config depending on the merge strategy specified by the
diff --git a/docs-starlight/src/assets/img/screenshots/custom-log-format-1.jpg b/docs-starlight/src/assets/img/screenshots/custom-log-format-1.jpg
new file mode 100644
index 00000000..7cd00655
Binary files /dev/null and b/docs-starlight/src/assets/img/screenshots/custom-log-format-1.jpg differ
diff --git a/docs-starlight/src/content/docs/04-reference/07-logging/02-formatting.md b/docs-starlight/src/content/docs/04-reference/07-logging/02-formatting.md
index 6f5c0a60..caaa3bfc 100644
--- a/docs-starlight/src/content/docs/04-reference/07-logging/02-formatting.md
+++ b/docs-starlight/src/content/docs/04-reference/07-logging/02-formatting.md
@@ -140,7 +140,7 @@ time=12:33:08.513 level=debug msg=Running command: tofu --version
 
 *Unfortunately, it is not possible to display color in a Markdown document, but in the above output, `time=` is colored magenta, `level=` is colored light blue and `msg=` is colored green.*
 
-[![screenshot](/assets/img/screenshots/custom-log-format-1.jpg){: width="50%" }](https://terragrunt.gruntwork.io/assets/img/screenshots/custom-log-format-1.jpg)
+![screenshot](../../../../assets/img/screenshots/custom-log-format-1.jpg)
 
 ## Options
 
diff --git a/docs/_docs/02_features/02-stacks.md b/docs/_docs/02_features/02-stacks.md
index 07e3840d..be846391 100644
--- a/docs/_docs/02_features/02-stacks.md
+++ b/docs/_docs/02_features/02-stacks.md
@@ -553,7 +553,7 @@ If real outputs only contain `vpc_id`, `dependency.outputs` will contain a real
 
 When defining a stack using a `terragrunt.stack.hcl` file, you also have the ability to interact with the aggregated outputs of all the units in the stack.
 
-To do this, use the [`stack output`](/docs/reference/cli/commands/stack/output) command (not the [`stack run output`](/docs/reference/cli/commands/stack/run) command).
+To do this, use the [`stack output`](/docs/reference/cli-options/#stack-output) command (not the [`stack run output`](/docs/reference/cli/commands/stack/run) command).
 
 ```bash
 $ terragrunt stack output
diff --git a/util/file.go b/util/file.go
index db242e0a..e41d330f 100644
--- a/util/file.go
+++ b/util/file.go
@@ -117,9 +117,15 @@ func GlobCanonicalPath(basePath string, globPaths ...string) ([]string, error) {
 			globPath = filepath.Join(basePath, globPath)
 		}
 
+		const stackDir = "/.terragrunt-stack/"
+
 		matches, err := zglob.Glob(globPath)
 		if err == nil {
 			paths = append(paths, matches...)
+		} else if errors.Is(err, os.ErrNotExist) && strings.Contains(CleanPath(globPath), stackDir) {
+			// when using the stack feature, the directory may not exist yet,
+			// as stack generation occurs after parsing the argument flags.
+			paths = append(paths, globPath)
 		}
 	}
 



Test patch:
diff --git a/config/include_test.go b/config/include_test.go
index ebd9cace..eb40191a 100644
--- a/config/include_test.go
+++ b/config/include_test.go
@@ -386,3 +386,35 @@ func TestConcurrentCopyFieldsMetadata(t *testing.T) {
 		t.Errorf("Expected %d fields, got %d", expectedFields, len(targetConfig.FieldsMetadata))
 	}
 }
+
+func TestDependencyFileNotFoundError(t *testing.T) {
+	t.Parallel()
+
+	// Test that DependencyFileNotFoundError is properly defined and formatted
+	err := config.DependencyFileNotFoundError{Path: "/test/path/terragrunt.hcl"}
+
+	assert.Equal(t, "/test/path/terragrunt.hcl", err.Path)
+	assert.Contains(t, err.Error(), "Dependency file not found: /test/path/terragrunt.hcl")
+
+	// Test with a different path
+	err2 := config.DependencyFileNotFoundError{Path: "/another/path/config.hcl"}
+	assert.Equal(t, "/another/path/config.hcl", err2.Path)
+	assert.Contains(t, err2.Error(), "Dependency file not found: /another/path/config.hcl")
+}
+
+func TestIncludeConfigNotFoundError(t *testing.T) {
+	t.Parallel()
+
+	// Test that IncludeConfigNotFoundError is properly defined and formatted
+	err := config.IncludeConfigNotFoundError{IncludePath: "/test/path/terragrunt.hcl", SourcePath: "/source/config.hcl"}
+
+	assert.Equal(t, "/test/path/terragrunt.hcl", err.IncludePath)
+	assert.Equal(t, "/source/config.hcl", err.SourcePath)
+	assert.Contains(t, err.Error(), "Include configuration not found: /test/path/terragrunt.hcl (referenced from: /source/config.hcl)")
+
+	// Test with a different path
+	err2 := config.IncludeConfigNotFoundError{IncludePath: "/another/path/config.hcl", SourcePath: "/different/source.hcl"}
+	assert.Equal(t, "/another/path/config.hcl", err2.IncludePath)
+	assert.Equal(t, "/different/source.hcl", err2.SourcePath)
+	assert.Contains(t, err2.Error(), "Include configuration not found: /another/path/config.hcl (referenced from: /different/source.hcl)")
+}
diff --git a/test/fixtures/stacks/all-no-stack-dir/live/terragrunt.stack.hcl b/test/fixtures/stacks/all-no-stack-dir/live/terragrunt.stack.hcl
new file mode 100644
index 00000000..a62ed739
--- /dev/null
+++ b/test/fixtures/stacks/all-no-stack-dir/live/terragrunt.stack.hcl
@@ -0,0 +1,12 @@
+unit "foo" {
+  source                  = "../unit"
+  path                    = "foo"
+  no_dot_terragrunt_stack = true
+}
+
+unit "bar" {
+  source                  = "../unit"
+  path                    = "bar"
+  no_dot_terragrunt_stack = true
+}
+
diff --git a/test/fixtures/stacks/all-no-stack-dir/unit/main.tf b/test/fixtures/stacks/all-no-stack-dir/unit/main.tf
new file mode 100644
index 00000000..ed7c4730
--- /dev/null
+++ b/test/fixtures/stacks/all-no-stack-dir/unit/main.tf
@@ -0,0 +1,8 @@
+output "test" {
+  value = var.test
+}
+
+variable "test" {
+  type = string
+}
+
diff --git a/test/fixtures/stacks/all-no-stack-dir/unit/terragrunt.hcl b/test/fixtures/stacks/all-no-stack-dir/unit/terragrunt.hcl
new file mode 100644
index 00000000..cad43b0c
--- /dev/null
+++ b/test/fixtures/stacks/all-no-stack-dir/unit/terragrunt.hcl
@@ -0,0 +1,8 @@
+terraform {
+  source = "."
+}
+
+inputs = {
+  test = "value"
+}
+
diff --git a/test/integration_stacks_test.go b/test/integration_stacks_test.go
index 1b9481c2..f9d68b42 100644
--- a/test/integration_stacks_test.go
+++ b/test/integration_stacks_test.go
@@ -48,9 +48,48 @@ const (
 	testFixtureStackNestedOutputs              = "fixtures/stacks/nested-outputs"
 	testFixtureStackNoValidation               = "fixtures/stacks/no-validation"
 	testFixtureStackTerragruntDir              = "fixtures/stacks/terragrunt-dir"
+	testFixtureStacksAllNoStackDir             = "fixtures/stacks/all-no-stack-dir"
 	testFixtureStackNoDotTerragruntStackOutput = "fixtures/stacks/no-dot-terragrunt-stack-output"
 )
 
+func TestStacksGenerateBasicWithQueueIncludeDirFlag(t *testing.T) {
+	t.Parallel()
+
+	helpers.CleanupTerraformFolder(t, testFixtureStacksBasic)
+	tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksBasic)
+	rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksBasic, "live")
+
+	_, stderr, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all plan --queue-include-dir .terragrunt-stack/chicks/chick-2 --working-dir "+rootPath)
+	require.NoError(t, err)
+
+	assert.NotContains(t, stderr, "- Unit ./.terragrunt-stack/chicks/chick-1")
+	assert.NotContains(t, stderr, "- Unit ./.terragrunt-stack/father")
+	assert.NotContains(t, stderr, "- Unit ./.terragrunt-stack/mother")
+	assert.Contains(t, stderr, "- Unit ./.terragrunt-stack/chicks/chick-2")
+
+	path := util.JoinPath(rootPath, ".terragrunt-stack")
+	validateStackDir(t, path)
+}
+
+func TestStacksGenerateBasicWithQueueExcludeDirFlag(t *testing.T) {
+	t.Parallel()
+
+	helpers.CleanupTerraformFolder(t, testFixtureStacksBasic)
+	tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksBasic)
+	rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksBasic, "live")
+
+	_, stderr, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all plan --queue-exclude-dir .terragrunt-stack/chicks/chick-2 --working-dir "+rootPath)
+	require.NoError(t, err)
+
+	assert.Contains(t, stderr, "- Unit ./.terragrunt-stack/chicks/chick-1")
+	assert.Contains(t, stderr, "- Unit ./.terragrunt-stack/father")
+	assert.Contains(t, stderr, "- Unit ./.terragrunt-stack/mother")
+	assert.NotContains(t, stderr, "- Unit ./.terragrunt-stack/chicks/chick-2")
+
+	path := util.JoinPath(rootPath, ".terragrunt-stack")
+	validateStackDir(t, path)
+}
+
 func TestStacksGenerateBasic(t *testing.T) {
 	t.Parallel()
 
@@ -1009,18 +1048,6 @@ func TestStacksNoStackDirDirectoryCreated(t *testing.T) {
 	assert.NoDirExists(t, path)
 }
 
-func TestStacksNoStackCommandFail(t *testing.T) {
-	t.Parallel()
-
-	helpers.CleanupTerraformFolder(t, testFixtureNoStackNoDir)
-	tmpEnvPath := helpers.CopyEnvironment(t, testFixtureNoStackNoDir)
-	rootPath := util.JoinPath(tmpEnvPath, testFixtureNoStackNoDir, "live")
-
-	_, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt stack run apply --non-interactive --working-dir "+rootPath)
-	require.Error(t, err)
-	assert.Contains(t, err.Error(), "Stack directory does not exist or is not accessible")
-}
-
 func TestStacksGeneratePrintWarning(t *testing.T) {
 	t.Parallel()
 
@@ -1316,6 +1343,36 @@ func TestStackTerragruntDir(t *testing.T) {
 	assert.Contains(t, out, `terragrunt_dir = "./tennant_1"`)
 }
 
+func TestStackRunAllNoStackDir(t *testing.T) {
+	t.Parallel()
+
+	helpers.CleanupTerraformFolder(t, testFixtureStacksAllNoStackDir)
+	tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksAllNoStackDir)
+
+	rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksAllNoStackDir, "live")
+
+	helpers.RunTerragrunt(t, "terragrunt stack generate --working-dir "+rootPath)
+
+	// Verify that no .terragrunt-stack directory was created since all units have no_dot_terragrunt_stack = true
+	stackDir := util.JoinPath(rootPath, ".terragrunt-stack")
+	stackDirExists := util.FileExists(stackDir)
+	t.Logf("Stack directory exists: %v", stackDirExists)
+
+	// Verify that units were generated in the same directory as terragrunt.stack.hcl
+	expectedUnits := []string{"foo", "bar"}
+	for _, unit := range expectedUnits {
+		unitPath := util.JoinPath(rootPath, unit)
+		assert.True(t, util.FileExists(unitPath), "Expected unit %s to exist in root directory", unit)
+		assert.True(t, util.FileExists(util.JoinPath(unitPath, "terragrunt.hcl")), "Expected terragrunt.hcl to exist in unit %s", unit)
+	}
+
+	stdout, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt stack run plan --non-interactive --working-dir "+rootPath)
+	require.NoError(t, err, "Expected stack run to succeed when all units have no_dot_terragrunt_stack = true")
+
+	assert.Contains(t, stdout, "Changes to Outputs:")
+	assert.Contains(t, stdout, "+ test = \"value\"")
+}
+
 func TestStackOutputWithNoDotTerragruntStack(t *testing.T) {
 	t.Parallel()