STET

agent_patch

runs/2026-02-28__13-38-10__gpt-5-3-codex/flux-pr-817/flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/agent-logs/agent.patch

21304 bytes

Back to adjudication
diff --git a/app/v2/pkg/engine/argumenttemplate/argument_template.go b/app/v2/pkg/engine/argumenttemplate/argument_template.go
new file mode 100644
index 0000000..dade16d
--- /dev/null
+++ b/app/v2/pkg/engine/argumenttemplate/argument_template.go
@@ -0,0 +1,170 @@
+package argumenttemplate
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	"github.com/wundergraph/graphql-go-tools/v2/pkg/ast"
+)
+
+var argumentTemplateRegex = regexp.MustCompile(`{{\s*args((?:\.[a-zA-Z0-9_]+)+)\s*}}`)
+
+type Match struct {
+	Start int
+	End   int
+	Path  []string
+}
+
+type ResolvedMatch struct {
+	Match
+	VariablePath    []string
+	VariableTypeRef int
+}
+
+func Parse(value string) []Match {
+	indices := argumentTemplateRegex.FindAllStringSubmatchIndex(value, -1)
+	if len(indices) == 0 {
+		return nil
+	}
+
+	out := make([]Match, 0, len(indices))
+	for _, idx := range indices {
+		// idx contains full match [0:2] and first submatch [2:4]
+		if len(idx) < 4 {
+			continue
+		}
+		path := value[idx[2]:idx[3]]
+		if len(path) < 2 {
+			continue
+		}
+		out = append(out, Match{
+			Start: idx[0],
+			End:   idx[1],
+			Path:  strings.Split(path[1:], "."),
+		})
+	}
+	return out
+}
+
+func Resolve(operation, definition *ast.Document, operationDefinitionRef, fieldRef int, value string) ([]ResolvedMatch, error) {
+	matches := Parse(value)
+	if len(matches) == 0 {
+		return nil, nil
+	}
+
+	out := make([]ResolvedMatch, 0, len(matches))
+	for _, match := range matches {
+		argumentName := match.Path[0]
+		argumentRef, ok := operation.FieldArgument(fieldRef, []byte(argumentName))
+		if !ok {
+			return nil, fmt.Errorf(`field argument "%s" is not defined`, argumentName)
+		}
+
+		argumentValue := operation.ArgumentValue(argumentRef)
+		if argumentValue.Kind != ast.ValueKindVariable {
+			return nil, fmt.Errorf(`expected argument "%s" kind to be "ValueKindVariable" but received "%s"`, argumentName, argumentValue.Kind)
+		}
+
+		variableNameBytes := operation.VariableValueNameBytes(argumentValue.Ref)
+		variableDefinitionRef, ok := operation.VariableDefinitionByNameAndOperation(operationDefinitionRef, variableNameBytes)
+		if !ok {
+			return nil, fmt.Errorf(`expected definition to exist for variable "%s"`, variableNameBytes)
+		}
+
+		variableTypeRef := operation.VariableDefinitions[variableDefinitionRef].Type
+		if err := validateArgumentPath(definition, operation, variableTypeRef, match.Path[1:]); err != nil {
+			return nil, fmt.Errorf(`invalid argument template path "%s": %w`, strings.Join(match.Path, "."), err)
+		}
+
+		variablePath := append([]string{string(variableNameBytes)}, match.Path[1:]...)
+		out = append(out, ResolvedMatch{
+			Match:           match,
+			VariablePath:    variablePath,
+			VariableTypeRef: variableTypeRef,
+		})
+	}
+
+	return out, nil
+}
+
+func validateArgumentPath(definition, typeDoc *ast.Document, typeRef int, nestedPath []string) error {
+	if len(nestedPath) == 0 {
+		if !isLeafType(definition, typeDoc, typeRef) {
+			return fmt.Errorf("template must resolve to a leaf input type")
+		}
+		return nil
+	}
+
+	currentTypeDoc := typeDoc
+	currentTypeRef := typeRef
+
+	for _, segment := range nestedPath {
+		if currentTypeDoc.TypeIsList(currentTypeRef) {
+			return fmt.Errorf("cannot select nested field %q on list type %q", segment, currentTypeDoc.ResolveTypeNameString(currentTypeRef))
+		}
+
+		typeName := currentTypeDoc.ResolveTypeNameString(currentTypeRef)
+		node, ok := definition.Index.FirstNodeByNameStr(typeName)
+		if !ok {
+			return fmt.Errorf("type %q not found in schema", typeName)
+		}
+		if node.Kind != ast.NodeKindInputObjectTypeDefinition {
+			return fmt.Errorf("cannot select nested field %q on non-input-object type %q", segment, typeName)
+		}
+
+		fieldRef := definition.InputObjectTypeDefinitionInputValueDefinitionByName(node.Ref, []byte(segment))
+		if fieldRef == -1 {
+			return fmt.Errorf("field %q not found on input object %q", segment, typeName)
+		}
+
+		currentTypeDoc = definition
+		currentTypeRef = definition.InputValueDefinitions[fieldRef].Type
+	}
+
+	if !isLeafType(definition, currentTypeDoc, currentTypeRef) {
+		return fmt.Errorf("template must resolve to a leaf input type")
+	}
+
+	return nil
+}
+
+func isLeafType(definition, typeDoc *ast.Document, typeRef int) bool {
+	typeName := typeDoc.ResolveTypeNameString(typeRef)
+	node, ok := definition.Index.FirstNodeByNameStr(typeName)
+	if !ok {
+		return false
+	}
+
+	return node.Kind == ast.NodeKindScalarTypeDefinition || node.Kind == ast.NodeKindEnumTypeDefinition
+}
+
+func ValidateNATSSubject(subject string, allowWildcards bool) error {
+	if subject == "" {
+		return fmt.Errorf("subject must not be empty")
+	}
+	if strings.ContainsAny(subject, " \t\r\n") {
+		return fmt.Errorf("subject must not contain whitespace")
+	}
+
+	tokens := strings.Split(subject, ".")
+	for i, token := range tokens {
+		if token == "" {
+			return fmt.Errorf("subject token at index %d must not be empty", i)
+		}
+		if strings.ContainsAny(token, "*>") {
+			if !allowWildcards {
+				return fmt.Errorf("subject token %q contains wildcard", token)
+			}
+			if token == "*" {
+				continue
+			}
+			if token == ">" && i == len(tokens)-1 {
+				continue
+			}
+			return fmt.Errorf("subject token %q has invalid wildcard usage", token)
+		}
+	}
+
+	return nil
+}
diff --git a/app/v2/pkg/engine/argumenttemplate/argument_template_test.go b/app/v2/pkg/engine/argumenttemplate/argument_template_test.go
new file mode 100644
index 0000000..f0d743a
--- /dev/null
+++ b/app/v2/pkg/engine/argumenttemplate/argument_template_test.go
@@ -0,0 +1,78 @@
+package argumenttemplate
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+	"github.com/wundergraph/graphql-go-tools/v2/pkg/ast"
+	"github.com/wundergraph/graphql-go-tools/v2/pkg/asttransform"
+	"github.com/wundergraph/graphql-go-tools/v2/pkg/internal/unsafeparser"
+)
+
+func TestResolve(t *testing.T) {
+	definition := unsafeparser.ParseGraphqlDocumentString(`
+		type Query {
+			user(id: ID!, input: UserInput!): String!
+		}
+
+		input UserInput {
+			id: ID!
+			nested: UserNestedInput!
+		}
+
+		input UserNestedInput {
+			name: String!
+		}
+	`)
+	require.NoError(t, asttransform.MergeDefinitionWithBaseSchema(&definition))
+
+	operation := unsafeparser.ParseGraphqlDocumentString(`
+		query UserQuery($id: ID!, $input: UserInput!) {
+			user(id: $id, input: $input)
+		}
+	`)
+
+	operationDefinitionRef, fieldRef := operationAndFieldRef(t, &operation)
+
+	t.Run("resolves multiple templates", func(t *testing.T) {
+		resolved, err := Resolve(&operation, &definition, operationDefinitionRef, fieldRef, "prefix.{{ args.id }}.{{ args.input.id }}")
+		require.NoError(t, err)
+		require.Len(t, resolved, 2)
+		require.Equal(t, []string{"id"}, resolved[0].Path)
+		require.Equal(t, []string{"id"}, resolved[0].VariablePath)
+		require.Equal(t, []string{"input", "id"}, resolved[1].Path)
+		require.Equal(t, []string{"input", "id"}, resolved[1].VariablePath)
+	})
+
+	t.Run("fails when nested segment does not exist", func(t *testing.T) {
+		_, err := Resolve(&operation, &definition, operationDefinitionRef, fieldRef, "{{ args.input.unknown }}")
+		require.Error(t, err)
+		require.ErrorContains(t, err, `field "unknown" not found`)
+	})
+
+	t.Run("fails when path ends on non-leaf type", func(t *testing.T) {
+		_, err := Resolve(&operation, &definition, operationDefinitionRef, fieldRef, "{{ args.input }}")
+		require.Error(t, err)
+		require.ErrorContains(t, err, "leaf input type")
+	})
+}
+
+func TestValidateNATSSubject(t *testing.T) {
+	require.NoError(t, ValidateNATSSubject("events.user.123", false))
+	require.NoError(t, ValidateNATSSubject("events.*.>", true))
+	require.Error(t, ValidateNATSSubject("events..123", false))
+	require.Error(t, ValidateNATSSubject("events.user.>", false))
+}
+
+func operationAndFieldRef(t *testing.T, operation *ast.Document) (int, int) {
+	t.Helper()
+
+	require.NotEmpty(t, operation.OperationDefinitions)
+	operationDefinitionRef := 0
+	selectionSetRef := operation.OperationDefinitions[operationDefinitionRef].SelectionSet
+	require.NotEmpty(t, operation.SelectionSets[selectionSetRef].SelectionRefs)
+	selectionRef := operation.SelectionSets[selectionSetRef].SelectionRefs[0]
+	require.Equal(t, ast.SelectionKindField, operation.Selections[selectionRef].Kind)
+
+	return operationDefinitionRef, operation.Selections[selectionRef].Ref
+}
diff --git a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/pubsub_datasource/nats_event_manager.go b/app/v2/pkg/engine/datasource/pubsub_datasource/nats_event_manager.go
index 1cb2914..773019e 100644
--- a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/pubsub_datasource/nats_event_manager.go
+++ b/app/v2/pkg/engine/datasource/pubsub_datasource/nats_event_manager.go
@@ -3,7 +3,9 @@ package pubsub_datasource
 import (
 	"encoding/json"
 	"fmt"
-	"github.com/wundergraph/graphql-go-tools/v2/pkg/ast"
+	"strings"
+
+	"github.com/wundergraph/graphql-go-tools/v2/pkg/engine/argumenttemplate"
 	"github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan"
 	"github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve"
 	"slices"
@@ -35,37 +37,50 @@ type NatsEventManager struct {
 }
 
 func (p *NatsEventManager) extractEventSubject(ref int, subject string) (string, error) {
-	matches := eventSubjectRegex.FindAllStringSubmatch(subject, -1)
-	if len(matches) != 1 || len(matches[0]) != 2 {
-		return "", fmt.Errorf("expected subject to match regex")
-	}
-	argumentName := matches[0][1]
-	// We need to find the argument in the operation
-	argumentRef, ok := p.visitor.Operation.FieldArgument(ref, []byte(argumentName))
-	if !ok {
-		return "", fmt.Errorf("argument \"%s\" is not defined", argumentName)
-	}
-	argumentValue := p.visitor.Operation.ArgumentValue(argumentRef)
-	if argumentValue.Kind != ast.ValueKindVariable {
-		return "", fmt.Errorf("expected argument \"%s\" kind to be \"ValueKindVariable\" but received \"%s\"", argumentName, argumentValue.Kind)
-	}
-	variableName := p.visitor.Operation.VariableValueNameBytes(argumentValue.Ref)
-	variableDefinition, ok := p.visitor.Operation.VariableDefinitionByNameAndOperation(p.visitor.Walker.Ancestors[0].Ref, variableName)
-	if !ok {
-		return "", fmt.Errorf("expected definition to exist for variable \"%s\"", variableName)
-	}
-	variableTypeRef := p.visitor.Operation.VariableDefinitions[variableDefinition].Type
-	renderer, err := resolve.NewPlainVariableRendererWithValidationFromTypeRef(p.visitor.Operation, p.visitor.Definition, variableTypeRef, string(variableName))
+	matches, err := argumenttemplate.Resolve(
+		p.visitor.Operation,
+		p.visitor.Definition,
+		p.visitor.Walker.Ancestors[0].Ref,
+		ref,
+		subject,
+	)
 	if err != nil {
 		return "", err
 	}
-	contextVariable := &resolve.ContextVariable{
-		Path:     []string{string(variableName)},
-		Renderer: renderer,
+
+	result := subject
+	if len(matches) > 0 {
+		var output strings.Builder
+		output.Grow(len(subject))
+		cursor := 0
+		for _, match := range matches {
+			output.WriteString(subject[cursor:match.Start])
+			renderer, err := resolve.NewPlainVariableRendererWithValidationFromTypeRef(
+				p.visitor.Operation,
+				p.visitor.Definition,
+				match.VariableTypeRef,
+				match.VariablePath...,
+			)
+			if err != nil {
+				return "", err
+			}
+			contextVariable := &resolve.ContextVariable{
+				Path:     match.VariablePath,
+				Renderer: renderer,
+			}
+			variablePlaceHolder, _ := p.variables.AddVariable(contextVariable) // $$0$$
+			output.WriteString(variablePlaceHolder)
+			cursor = match.End
+		}
+		output.WriteString(subject[cursor:])
+		result = output.String()
+	}
+
+	allowWildcards := p.eventMetadata.Type == EventTypeSubscribe
+	if err := argumenttemplate.ValidateNATSSubject(result, allowWildcards); err != nil {
+		return "", err
 	}
-	// We need to replace the template literal with the variable placeholder (and reuse if it already exists)
-	variablePlaceHolder, _ := p.variables.AddVariable(contextVariable) // $$0$$
-	return eventSubjectRegex.ReplaceAllLiteralString(subject, variablePlaceHolder), nil
+	return result, nil
 }
 
 func (p *NatsEventManager) eventDataBytes(ref int) ([]byte, error) {
diff --git a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go b/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go
index 02b05d3..4c62615 100644
--- a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go
+++ b/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go
@@ -5,7 +5,6 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"regexp"
 	"strings"
 
 	"github.com/jensneuse/abstractlogger"
@@ -23,8 +22,6 @@ const (
 	EventTypeSubscribe EventType = "subscribe"
 )
 
-var eventSubjectRegex = regexp.MustCompile(`{{ args.([a-zA-Z0-9_]+) }}`)
-
 func EventTypeFromString(s string) (EventType, error) {
 	et := EventType(strings.ToLower(s))
 	switch et {
diff --git a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource_test.go b/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource_test.go
index 2c817b1..f700092 100644
--- a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource_test.go
+++ b/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource_test.go
@@ -44,6 +44,7 @@ func TestPubSub(t *testing.T) {
 	type Subscription {
 		helloSubscription(id: String!): String! @eventsSubscribe(subjects: ["helloSubscription.{{ args.id }}"])
 		subscriptionWithMultipleSubjects(firstId: String!, secondId: String!): String! @eventsSubscribe(subjects: ["firstSubscription.{{ args.firstId }}", "secondSubscription.{{ args.secondId }}"])
+		subscriptionWithMultipleTemplatesInSingleSubject(firstId: String!, secondId: String!): String! @eventsSubscribe(subjects: ["combined.{{ args.firstId }}.{{ args.secondId }}"])
 	}`
 
 	dataSourceCustomConfig := Configuration{
@@ -92,6 +93,17 @@ func TestPubSub(t *testing.T) {
 					Subjects: []string{"firstSubscription.{{ args.firstId }}", "secondSubscription.{{ args.secondId }}"},
 				},
 			},
+			{
+				Metadata: &EventMetadata{
+					ProviderID: "default",
+					FieldName:  "subscriptionWithMultipleTemplatesInSingleSubject",
+					Type:       EventTypeSubscribe,
+					TypeName:   "Subscription",
+				},
+				Configuration: &NatsEventConfiguration{
+					Subjects: []string{"combined.{{ args.firstId }}.{{ args.secondId }}"},
+				},
+			},
 		},
 	}
 
@@ -116,6 +128,10 @@ func TestPubSub(t *testing.T) {
 					TypeName:   "Subscription",
 					FieldNames: []string{"subscriptionWithMultipleSubjects"},
 				},
+				{
+					TypeName:   "Subscription",
+					FieldNames: []string{"subscriptionWithMultipleTemplatesInSingleSubject"},
+				},
 			},
 		},
 		dataSourceCustomConfig,
@@ -171,6 +187,20 @@ func TestPubSub(t *testing.T) {
 					},
 				},
 			},
+			{
+				TypeName:  "Subscription",
+				FieldName: "subscriptionWithMultipleTemplatesInSingleSubject",
+				Arguments: []plan.ArgumentConfiguration{
+					{
+						Name:       "firstId",
+						SourceType: plan.FieldArgumentSource,
+					},
+					{
+						Name:       "secondId",
+						SourceType: plan.FieldArgumentSource,
+					},
+				},
+			},
 		},
 		DisableResolveFieldPositions: true,
 	}
@@ -332,4 +362,45 @@ func TestPubSub(t *testing.T) {
 		}
 		datasourcetesting.RunTest(schema, operation, operationName, expect, planConfig)(t)
 	})
+
+	t.Run("subscription with multiple templates in a single subject", func(t *testing.T) {
+		const operation = "subscription SubscriptionWithMultipleTemplatesInSingleSubject { subscriptionWithMultipleTemplatesInSingleSubject(firstId: 11, secondId: 23) }"
+		const operationName = `SubscriptionWithMultipleTemplatesInSingleSubject`
+		expect := &plan.SubscriptionResponsePlan{
+			Response: &resolve.GraphQLSubscription{
+				Trigger: resolve.GraphQLSubscriptionTrigger{
+					Input: []byte(`{"providerId":"default","subjects":["combined.$$0$$.$$1$$"]}`),
+					Variables: resolve.Variables{
+						&resolve.ContextVariable{
+							Path:     []string{"a"},
+							Renderer: resolve.NewPlainVariableRendererWithValidation(`{"type":["string"]}`),
+						},
+						&resolve.ContextVariable{
+							Path:     []string{"b"},
+							Renderer: resolve.NewPlainVariableRendererWithValidation(`{"type":["string"]}`),
+						},
+					},
+					Source: &NatsSubscriptionSource{
+						pubSub: &testPubsub{},
+					},
+					PostProcessing: resolve.PostProcessingConfiguration{
+						MergePath: []string{"subscriptionWithMultipleTemplatesInSingleSubject"},
+					},
+				},
+				Response: &resolve.GraphQLResponse{
+					Data: &resolve.Object{
+						Fields: []*resolve.Field{
+							{
+								Name: []byte("subscriptionWithMultipleTemplatesInSingleSubject"),
+								Value: &resolve.String{
+									Path: []string{"subscriptionWithMultipleTemplatesInSingleSubject"},
+								},
+							},
+						},
+					},
+				},
+			},
+		}
+		datasourcetesting.RunTest(schema, operation, operationName, expect, planConfig)(t)
+	})
 }
diff --git a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/configuration_visitor.go b/app/v2/pkg/engine/plan/configuration_visitor.go
index b5e2ed1..ea3aafc 100644
--- a/tmp/agent-patch-flux-pr-817.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/configuration_visitor.go
+++ b/app/v2/pkg/engine/plan/configuration_visitor.go
@@ -3,7 +3,6 @@ package plan
 import (
 	"bytes"
 	"fmt"
-	"regexp"
 	"slices"
 	"strings"
 
@@ -12,6 +11,7 @@ import (
 
 	"github.com/wundergraph/graphql-go-tools/v2/pkg/ast"
 	"github.com/wundergraph/graphql-go-tools/v2/pkg/astvisitor"
+	"github.com/wundergraph/graphql-go-tools/v2/pkg/engine/argumenttemplate"
 	"github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve"
 )
 
@@ -870,13 +870,6 @@ func (c *configurationVisitor) buildSubscriptionFilterCondition(condition Subscr
 	return filter
 }
 
-var (
-	// subscriptionFieldFilterRegex is used to extract the variable name from the subscription filter condition
-	// e.g. {{ args.id }} -> id
-	// e.g. {{ args.input.id }} -> input.id
-	subscriptionFieldFilterRegex = regexp.MustCompile(`{{\s*args((?:\.[a-zA-Z0-9_]+)+)\s*}}`)
-)
-
 // ContainsTemplateString checks if the value contains a template string
 func ContainsTemplateString(value []byte) bool {
 	return bytes.Contains(value, []byte("{{"))
@@ -887,7 +880,11 @@ func (c *configurationVisitor) buildSubscriptionFieldFilter(condition *Subscript
 	filter.FieldPath = condition.FieldPath
 	filter.Values = make([]resolve.InputTemplate, len(condition.Values))
 	for i, value := range condition.Values {
-		matches := subscriptionFieldFilterRegex.FindAllStringSubmatchIndex(value, -1)
+		parsedMatches := argumenttemplate.Parse(value)
+		if len(parsedMatches) > 1 {
+			return nil
+		}
+		matches, err := argumenttemplate.Resolve(c.operation, c.definition, c.walker.Ancestors[0].Ref, c.fieldRef, value)
 		if len(matches) == 0 {
 			filter.Values[i].Segments = []resolve.TemplateSegment{
 				{
@@ -897,26 +894,15 @@ func (c *configurationVisitor) buildSubscriptionFieldFilter(condition *Subscript
 			}
 			continue
 		}
-		if len(matches) == 1 && len(matches[0]) == 4 {
-			prefix := value[:matches[0][0]]
+		if err != nil {
+			c.walker.StopWithInternalErr(err)
+			return nil
+		}
+		if len(matches) == 1 {
+			match := matches[0]
+			prefix := value[:match.Start]
 			hasPrefix := len(prefix) > 0
-			// the path begins with ".", so ignore the first empty string element with trailing [1:]
-			argumentPath := strings.Split(value[matches[0][2]:matches[0][3]][1:], ".")
-			argumentName := argumentPath[0]
-			argumentRef, ok := c.operation.FieldArgument(c.fieldRef, []byte(argumentName))
-			if !ok {
-				c.walker.StopWithInternalErr(fmt.Errorf(`field argument "%s" is not defined`, argumentName))
-				return nil
-			}
-			argumentValue := c.operation.ArgumentValue(argumentRef)
-			if argumentValue.Kind != ast.ValueKindVariable {
-				c.walker.StopWithInternalErr(fmt.Errorf(`expected argument "%s" kind to be "ValueKindVariable" but received "%s"`, argumentName, argumentValue.Kind))
-				return nil
-			}
-			variableName := c.operation.VariableValueNameString(argumentValue.Ref)
-			// the variable path should be the variable name, e.g., "a", and then the 2nd element from the path onwards
-			variablePath := append([]string{variableName}, argumentPath[1:]...)
-			suffix := value[matches[0][1]:]
+			suffix := value[match.End:]
 			hasSuffix := len(suffix) > 0
 			size := 1
 			if hasPrefix {
@@ -938,7 +924,7 @@ func (c *configurationVisitor) buildSubscriptionFieldFilter(condition *Subscript
 				SegmentType:        resolve.VariableSegmentType,
 				VariableKind:       resolve.ContextVariableKind,
 				Renderer:           resolve.NewPlainVariableRenderer(),
-				VariableSourcePath: variablePath,
+				VariableSourcePath: match.VariablePath,
 			}
 			if hasSuffix {
 				filter.Values[i].Segments[idx+1] = resolve.TemplateSegment{