diff --git a/.changeset/plenty-sheep-clean.md b/.changeset/plenty-sheep-clean.md
new file mode 100644
index 000000000..3949bc770
--- /dev/null
+++ b/.changeset/plenty-sheep-clean.md
@@ -0,0 +1,5 @@
+---
+"@effect/schema": patch
+---
+
+fix encode discriminated union with transformation
diff --git a/src/Parser.ts b/src/Parser.ts
index 2bdee8b42..c7df60202 100644
--- a/src/Parser.ts
+++ b/src/Parser.ts
@@ -808,7 +808,7 @@ const go = (ast: AST.AST, isDecoding: boolean): Parser<any, any> => {
       }
     }
     case "Union": {
-      const searchTree = _getSearchTree(ast.types)
+      const searchTree = _getSearchTree(ast.types, isDecoding)
       const ownKeys = Internal.ownKeys(searchTree.keys)
       const len = ownKeys.length
       const map = new Map<any, Parser<any, any>>()
@@ -942,16 +942,17 @@ const fromRefinement =
 
 /** @internal */
 export const _getLiterals = (
-  ast: AST.AST
+  ast: AST.AST,
+  isDecoding: boolean
 ): ReadonlyArray<[PropertyKey, AST.Literal]> => {
   switch (ast._tag) {
     case "Declaration":
-      return _getLiterals(ast.type)
+      return _getLiterals(ast.type, isDecoding)
     case "TypeLiteral": {
       const out: Array<[PropertyKey, AST.Literal]> = []
       for (let i = 0; i < ast.propertySignatures.length; i++) {
         const propertySignature = ast.propertySignatures[i]
-        const type = AST.from(propertySignature.type)
+        const type = isDecoding ? AST.from(propertySignature.type) : AST.to(propertySignature.type)
         if (AST.isLiteral(type) && !propertySignature.isOptional) {
           out.push([propertySignature.name, type])
         }
@@ -959,8 +960,9 @@ export const _getLiterals = (
       return out
     }
     case "Refinement":
+      return _getLiterals(ast.from, isDecoding)
     case "Transform":
-      return _getLiterals(ast.from)
+      return _getLiterals(isDecoding ? ast.from : ast.to, isDecoding)
   }
   return []
 }
@@ -980,7 +982,8 @@ export const _getLiterals = (
  * @internal
  */
 export const _getSearchTree = (
-  members: ReadonlyArray<AST.AST>
+  members: ReadonlyArray<AST.AST>,
+  isDecoding: boolean
 ): {
   keys: {
     readonly [key: PropertyKey]: {
@@ -999,7 +1002,7 @@ export const _getSearchTree = (
   const otherwise: Array<AST.AST> = []
   for (let i = 0; i < members.length; i++) {
     const member = members[i]
-    const tags = _getLiterals(member)
+    const tags = _getLiterals(member, isDecoding)
     if (tags.length > 0) {
       for (let j = 0; j < tags.length; j++) {
         const [key, literal] = tags[j]
diff --git a/test/Parser.test.ts b/test/Parser.test.ts
index 790775f05..0e63a368d 100644
--- a/test/Parser.test.ts
+++ b/test/Parser.test.ts
@@ -130,6 +130,34 @@ describe("Parser", () => {
   it("encodeEither", () => {
     const schema = S.NumberFromString
     expect(P.encodeEither(schema)(1)).toEqual(E.right("1"))
+    expect(
+      P.encodeEither(
+        S.union(
+          S.transform(
+            S.struct({ _tag: S.literal("a") }),
+            S.struct({ _tag: S.literal("b") }),
+            () => ({ _tag: "b" as const }),
+            () => ({ _tag: "a" as const })
+          ),
+          S.struct({ _tag: S.literal("c") })
+        )
+      )({ _tag: "b" })
+    ).toEqual(E.right({ _tag: "a" }))
+    expect(
+      P.encodeEither(
+        S.union(
+          S.struct({
+            _tag: S.transform(
+              S.literal("a"),
+              S.literal("b"),
+              () => "b" as const,
+              () => "a" as const
+            )
+          }),
+          S.struct({ _tag: S.literal("c") })
+        )
+      )({ _tag: "b" })
+    ).toEqual(E.right({ _tag: "a" }))
   })
 
   it("encodePromise", async () => {
@@ -138,16 +166,17 @@ describe("Parser", () => {
   })
 
   it("_getLiterals", () => {
-    expect(P._getLiterals(S.string.ast)).toEqual([])
+    expect(P._getLiterals(S.string.ast, true)).toEqual([])
     // TypeLiteral
-    expect(P._getLiterals(S.struct({ _tag: S.literal("a") }).ast))
+    expect(P._getLiterals(S.struct({ _tag: S.literal("a") }).ast, true))
       .toEqual([["_tag", AST.createLiteral("a")]])
     // Refinement
     expect(
       P._getLiterals(
         S.struct({ _tag: S.literal("a") }).pipe(
           S.filter(() => true)
-        ).ast
+        ).ast,
+        true
       )
     ).toEqual([["_tag", AST.createLiteral("a")]])
     // declare
@@ -157,25 +186,49 @@ describe("Parser", () => {
           [],
           S.struct({ _tag: S.literal("a") }),
           () => P.parse(S.struct({ _tag: S.literal("a") }))
-        ).ast
+        ).ast,
+        true
       )
     ).toEqual([["_tag", AST.createLiteral("a")]])
 
     // Transform
     expect(
       P._getLiterals(
-        S.struct({ radius: S.number }).pipe(S.attachPropertySignature("kind", "circle")).ast
+        S.struct({ radius: S.number }).pipe(S.attachPropertySignature("kind", "circle")).ast,
+        true
       )
     ).toEqual([])
+    // Transform encode
+    expect(
+      P._getLiterals(
+        S.struct({ radius: S.number }).pipe(S.attachPropertySignature("kind", "circle")).ast,
+        false
+      )
+    ).toEqual([["kind", AST.createLiteral("circle")]])
+    // property Transform encode
+    expect(
+      P._getLiterals(
+        S.struct({
+          _tag: S.transform(
+            S.literal("a"),
+            S.literal("b"),
+            () => "b" as const,
+            () => "a" as const
+          )
+        })
+          .ast,
+        false
+      )
+    ).toEqual([["_tag", AST.createLiteral("b")]])
   })
 
   it("_getSearchTree", () => {
-    expect(P._getSearchTree([S.string.ast, S.number.ast])).toEqual({
+    expect(P._getSearchTree([S.string.ast, S.number.ast], true)).toEqual({
       keys: {},
       otherwise: [S.string.ast, S.number.ast]
     })
 
-    expect(P._getSearchTree([S.struct({ _tag: S.literal("a") }).ast, S.number.ast])).toEqual(
+    expect(P._getSearchTree([S.struct({ _tag: S.literal("a") }).ast, S.number.ast], true)).toEqual(
       {
         keys: {
           _tag: {
@@ -193,7 +246,7 @@ describe("Parser", () => {
       P._getSearchTree([
         S.struct({ _tag: S.literal("a") }).ast,
         S.struct({ _tag: S.literal("b") }).ast
-      ])
+      ], true)
     ).toEqual({
       keys: {
         _tag: {
@@ -211,7 +264,7 @@ describe("Parser", () => {
       P._getSearchTree([
         S.struct({ a: S.literal("A"), c: S.string }).ast,
         S.struct({ b: S.literal("B"), d: S.number }).ast
-      ])
+      ], true)
     ).toEqual({
       keys: {
         a: {
@@ -236,7 +289,7 @@ describe("Parser", () => {
         S.struct({ category: S.literal("catA"), tag: S.literal("a") }).ast,
         S.struct({ category: S.literal("catA"), tag: S.literal("b") }).ast,
         S.struct({ category: S.literal("catA"), tag: S.literal("c") }).ast
-      ])
+      ], true)
     ).toEqual({
       keys: {
         category: {
@@ -271,7 +324,7 @@ describe("Parser", () => {
     )
     const types = (schema.ast as AST.Union).types
     expect(
-      P._getSearchTree(types)
+      P._getSearchTree(types, true)
     ).toEqual({
       keys: {
         type: {