diff --git a/backend/runner/pubsub/integration_test.go b/backend/runner/pubsub/integration_test.go
index af10cb4f97..62c22d7991 100644
--- a/backend/runner/pubsub/integration_test.go
+++ b/backend/runner/pubsub/integration_test.go
@@ -74,7 +74,7 @@ func TestRetry(t *testing.T) {
 		checkConsumed("subscriber", "consumeButFailAndRetry", false, retriesPerCall+1, optional.Some("secondCall")),
 		checkPublished("subscriber", "consumeButFailAndRetryFailed", 2),
 
-		in.IfLanguage("go", checkConsumed("subscriber", "consumeFromDeadLetter", true, 2, optional.None[string]())),
+		checkConsumed("subscriber", "consumeFromDeadLetter", true, 2, optional.None[string]()),
 	)
 }
 
diff --git a/jvm-runtime/jvm_integration_test.go b/jvm-runtime/jvm_integration_test.go
index 7fed09287b..d187f45f51 100644
--- a/jvm-runtime/jvm_integration_test.go
+++ b/jvm-runtime/jvm_integration_test.go
@@ -152,6 +152,7 @@ func TestJVMCoreFunctionality(t *testing.T) {
 		})
 	})...)
 	tests = append(tests, AllRuntimesVerbTest("testObjectVerb", exampleObject)...)
+	tests = append(tests, AllRuntimesVerbTest("testGenericType", FailedEvent[TestObject]{Event: exampleObject, Error: "failed"})...)
 	tests = append(tests, AllRuntimesVerbTest("testObjectOptionalFieldsVerb", exampleOptionalFieldsObject)...)
 	tests = append(tests, AllRuntimesVerbTest("objectMapVerb", map[string]TestObject{"hello": exampleObject})...)
 	tests = append(tests, AllRuntimesVerbTest("objectArrayVerb", []TestObject{exampleObject})...)
@@ -480,3 +481,8 @@ type Thing struct{}
 
 func (Word) tag()  {}
 func (Thing) tag() {}
+
+type FailedEvent[Event any] struct {
+	Event Event  `json:"event"`
+	Error string `json:"error"`
+}
diff --git a/jvm-runtime/testdata/go/gomodule/server.go b/jvm-runtime/testdata/go/gomodule/server.go
index 55200a80a5..9604ad9ba3 100644
--- a/jvm-runtime/testdata/go/gomodule/server.go
+++ b/jvm-runtime/testdata/go/gomodule/server.go
@@ -5,6 +5,8 @@ import (
 	"fmt"
 	"time"
 
+	"ftl/builtin"
+
 	"github.com/decentralized-identity/web5-go/dids/did"
 
 	"github.com/block/ftl/go-runtime/ftl"
@@ -219,6 +221,11 @@ func TestObjectVerb(ctx context.Context, val TestObject) (TestObject, error) {
 	return val, nil
 }
 
+//ftl:verb export
+func TestGenericType(ctx context.Context, val builtin.FailedEvent[TestObject]) (builtin.FailedEvent[TestObject], error) {
+	return val, nil
+}
+
 //ftl:verb export
 func TestObjectOptionalFieldsVerb(ctx context.Context, val TestObjectOptionalFields) (TestObjectOptionalFields, error) {
 	return val, nil
diff --git a/jvm-runtime/testdata/go/gomodule/types.ftl.go b/jvm-runtime/testdata/go/gomodule/types.ftl.go
index 0a90cefcb4..cb44a196a4 100644
--- a/jvm-runtime/testdata/go/gomodule/types.ftl.go
+++ b/jvm-runtime/testdata/go/gomodule/types.ftl.go
@@ -3,8 +3,9 @@ package gomodule
 
 import (
 	"context"
-	"github.com/block/ftl/go-runtime/ftl"
+	ftlbuiltin "ftl/builtin"
 	"github.com/block/ftl/common/reflection"
+	"github.com/block/ftl/go-runtime/ftl"
 	"github.com/decentralized-identity/web5-go/dids/did"
 	stdtime "time"
 )
@@ -65,6 +66,8 @@ type StringMapVerbClient func(context.Context, map[string]string) (map[string]st
 
 type StringVerbClient func(context.Context, string) (string, error)
 
+type TestGenericTypeClient func(context.Context, ftlbuiltin.FailedEvent[TestObject]) (ftlbuiltin.FailedEvent[TestObject], error)
+
 type TestObjectOptionalFieldsVerbClient func(context.Context, TestObjectOptionalFields) (TestObjectOptionalFields, error)
 
 type TestObjectVerbClient func(context.Context, TestObject) (TestObject, error)
@@ -172,6 +175,9 @@ func init() {
 		reflection.ProvideResourcesForVerb(
 			StringVerb,
 		),
+		reflection.ProvideResourcesForVerb(
+			TestGenericType,
+		),
 		reflection.ProvideResourcesForVerb(
 			TestObjectOptionalFieldsVerb,
 		),
diff --git a/jvm-runtime/testdata/java/javaclient/src/main/java/xyz/block/ftl/test/TestInvokeGoFromJava.java b/jvm-runtime/testdata/java/javaclient/src/main/java/xyz/block/ftl/test/TestInvokeGoFromJava.java
index b3e003255a..4e48a47475 100644
--- a/jvm-runtime/testdata/java/javaclient/src/main/java/xyz/block/ftl/test/TestInvokeGoFromJava.java
+++ b/jvm-runtime/testdata/java/javaclient/src/main/java/xyz/block/ftl/test/TestInvokeGoFromJava.java
@@ -7,47 +7,8 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import ftl.gomodule.AnimalWrapper;
-import ftl.gomodule.BoolVerbClient;
-import ftl.gomodule.BytesVerbClient;
-import ftl.gomodule.ColorWrapper;
-import ftl.gomodule.EmptyVerbClient;
-import ftl.gomodule.ErrorEmptyVerbClient;
-import ftl.gomodule.ExternalTypeVerbClient;
-import ftl.gomodule.FloatVerbClient;
-import ftl.gomodule.IntVerbClient;
-import ftl.gomodule.ObjectArrayVerbClient;
-import ftl.gomodule.ObjectMapVerbClient;
-import ftl.gomodule.OptionalBoolVerbClient;
-import ftl.gomodule.OptionalBytesVerbClient;
-import ftl.gomodule.OptionalFloatVerbClient;
-import ftl.gomodule.OptionalIntVerbClient;
-import ftl.gomodule.OptionalStringArrayVerbClient;
-import ftl.gomodule.OptionalStringMapVerbClient;
-import ftl.gomodule.OptionalStringVerbClient;
-import ftl.gomodule.OptionalTestObjectOptionalFieldsVerbClient;
-import ftl.gomodule.OptionalTestObjectVerbClient;
-import ftl.gomodule.OptionalTimeVerbClient;
-import ftl.gomodule.ParameterizedObjectVerbClient;
-import ftl.gomodule.ParameterizedType;
-import ftl.gomodule.Scalar;
-import ftl.gomodule.ShapeWrapper;
-import ftl.gomodule.SinkVerbClient;
-import ftl.gomodule.SourceVerbClient;
-import ftl.gomodule.StringArrayVerbClient;
-import ftl.gomodule.StringEnumVerbClient;
-import ftl.gomodule.StringList;
-import ftl.gomodule.StringMapVerbClient;
-import ftl.gomodule.StringVerbClient;
-import ftl.gomodule.TestObject;
-import ftl.gomodule.TestObjectOptionalFields;
-import ftl.gomodule.TestObjectOptionalFieldsVerbClient;
-import ftl.gomodule.TestObjectVerbClient;
-import ftl.gomodule.TimeVerbClient;
-import ftl.gomodule.TypeEnumVerbClient;
-import ftl.gomodule.TypeEnumWrapper;
-import ftl.gomodule.TypeWrapperEnumVerbClient;
-import ftl.gomodule.ValueEnumVerbClient;
+import ftl.builtin.FailedEvent;
+import ftl.gomodule.*;
 import web5.sdk.dids.didcore.Did;
 import xyz.block.ftl.Export;
 import xyz.block.ftl.Verb;
@@ -154,6 +115,13 @@ public boolean boolVerb(boolean val, BoolVerbClient client) {
         return client.testObjectVerb(val);
     }
 
+    @Export
+    @Verb
+    public @NotNull FailedEvent<TestObject> testGenericType(@NotNull FailedEvent<TestObject> val,
+            TestGenericTypeClient client) {
+        return client.testGenericType(val);
+    }
+
     @Export
     @Verb
     public @NotNull TestObjectOptionalFields testObjectOptionalFieldsVerb(@NotNull TestObjectOptionalFields val,
diff --git a/jvm-runtime/testdata/kotlin/kotlinmodule/src/main/kotlin/xyz/block/ftl/test/TestInvokeGoFromKotlin.kt b/jvm-runtime/testdata/kotlin/kotlinmodule/src/main/kotlin/xyz/block/ftl/test/TestInvokeGoFromKotlin.kt
index efb225e6d6..26ec497604 100644
--- a/jvm-runtime/testdata/kotlin/kotlinmodule/src/main/kotlin/xyz/block/ftl/test/TestInvokeGoFromKotlin.kt
+++ b/jvm-runtime/testdata/kotlin/kotlinmodule/src/main/kotlin/xyz/block/ftl/test/TestInvokeGoFromKotlin.kt
@@ -1,5 +1,6 @@
 package xyz.block.ftl.test
 
+import ftl.builtin.FailedEvent
 import ftl.gomodule.*
 import web5.sdk.dids.didcore.Did
 import xyz.block.ftl.Export
@@ -117,6 +118,12 @@ fun testObjectOptionalFieldsVerb(
   return client.testObjectOptionalFieldsVerb(payload)
 }
 
+@Export
+@Verb
+fun testGenericType(payload: FailedEvent<TestObject>, client: TestGenericTypeClient): FailedEvent<TestObject> {
+  return client.testGenericType(payload)
+}
+
 // now the same again but with option return / input types
 @Export
 @Verb