diff --git a/.changeset/hot-dogs-mix.md b/.changeset/hot-dogs-mix.md
new file mode 100644
index 0000000000..ddcdf696df
--- /dev/null
+++ b/.changeset/hot-dogs-mix.md
@@ -0,0 +1,5 @@
+---
+"effect": minor
+---
+
+New constructor Config.stringNonEmpty
diff --git a/packages/effect/src/Config.ts b/packages/effect/src/Config.ts
index 294157446c..221ee024e6 100644
--- a/packages/effect/src/Config.ts
+++ b/packages/effect/src/Config.ts
@@ -367,6 +367,14 @@ export const hashSet: (config: Config, name?: string) => Config Config = internal.string
+/**
+ * Constructs a config for a non-empty string value.
+ *
+ * @since 3.7.0
+ * @category constructors
+ */
+export const stringNonEmpty: (name?: string) => Config = internal.stringNonEmpty
+
/**
* Constructs a config which contains the specified value.
*
diff --git a/packages/effect/src/internal/config.ts b/packages/effect/src/internal/config.ts
index d3125aa1c2..44e805ec5f 100644
--- a/packages/effect/src/internal/config.ts
+++ b/packages/effect/src/internal/config.ts
@@ -447,6 +447,16 @@ export const string = (name?: string): Config.Config => {
return name === undefined ? config : nested(config, name)
}
+/** @internal */
+export const stringNonEmpty = (name?: string): Config.Config => {
+ const config = primitive(
+ "a non-empty text property",
+ Either.liftPredicate((text) => text.length > 0, () => configError.MissingData([], "Expected a non-empty string"))
+ )
+
+ return name === undefined ? config : nested(config, name)
+}
+
/** @internal */
export const all = > | Record>>(
arg: Arg
diff --git a/packages/effect/test/Config.test.ts b/packages/effect/test/Config.test.ts
index 00ec1ecc4c..a96a8cf191 100644
--- a/packages/effect/test/Config.test.ts
+++ b/packages/effect/test/Config.test.ts
@@ -66,6 +66,25 @@ describe("Config", () => {
})
})
+ describe("stringNonEmpty", () => {
+ it("name = undefined", () => {
+ const config = Config.array(Config.stringNonEmpty(), "ITEMS")
+ assertSuccess(config, [["ITEMS", "foo"]], ["foo"])
+ assertFailure(config, [["ITEMS", ""]], ConfigError.MissingData(["ITEMS"], "Expected a non-empty string"))
+ })
+
+ it("name != undefined", () => {
+ const config = Config.stringNonEmpty("NON_EMPTY_STRING")
+ assertSuccess(config, [["NON_EMPTY_STRING", "foo"]], "foo")
+ assertSuccess(config, [["NON_EMPTY_STRING", " "]], " ")
+ assertFailure(
+ config,
+ [["NON_EMPTY_STRING", ""]],
+ ConfigError.MissingData(["NON_EMPTY_STRING"], "Expected a non-empty string")
+ )
+ })
+ })
+
describe("number", () => {
it("name = undefined", () => {
const config = Config.array(Config.number(), "ITEMS")