diff --git a/src/utilities/TypeInfo.ts b/src/utilities/TypeInfo.ts
index e2c9683835..acc3c43926 100644
--- a/src/utilities/TypeInfo.ts
+++ b/src/utilities/TypeInfo.ts
@@ -116,6 +116,8 @@ export class TypeInfo {
     return this._inputTypeStack.at(-1);
   }
 
+  // Note: continues to expose the closest enclosing valid input type if
+  // traversal descends into syntax with no corresponding GraphQL input type.
   getParentInputType(): Maybe<GraphQLInputType> {
     return this._inputTypeStack.at(-2);
   }
@@ -254,7 +256,7 @@ export class TypeInfo {
         const listType: unknown = getNullableType(this.getInputType());
         const itemType: unknown = isListType(listType)
           ? listType.ofType
-          : listType;
+          : undefined;
         // List positions never have a default value.
         this._defaultValueStack.push(undefined);
         this._inputTypeStack.push(isInputType(itemType) ? itemType : undefined);
diff --git a/src/utilities/__tests__/TypeInfo-test.ts b/src/utilities/__tests__/TypeInfo-test.ts
index cc129287c3..1691dfff70 100644
--- a/src/utilities/__tests__/TypeInfo-test.ts
+++ b/src/utilities/__tests__/TypeInfo-test.ts
@@ -519,6 +519,121 @@ describe('visitWithTypeInfo', () => {
     ]);
   });
 
+  it('supports traversals of object literals in custom scalar positions', () => {
+    const schema = buildSchema(`
+      scalar GeoPoint
+    `);
+    const ast = parseValue('{x: 4.0, y: 2.0}');
+    const scalarType = schema.getType('GeoPoint');
+    assert(scalarType != null);
+
+    const typeInfo = new TypeInfo(schema, scalarType);
+
+    const visited: Array<any> = [];
+    visit(
+      ast,
+      visitWithTypeInfo(typeInfo, {
+        enter(node) {
+          const type = typeInfo.getInputType();
+          const parentType = typeInfo.getParentInputType();
+          visited.push([
+            'enter',
+            node.kind,
+            node.kind === 'Name' ? node.value : null,
+            String(type),
+            String(parentType),
+          ]);
+        },
+        leave(node) {
+          const type = typeInfo.getInputType();
+          const parentType = typeInfo.getParentInputType();
+          visited.push([
+            'leave',
+            node.kind,
+            node.kind === 'Name' ? node.value : null,
+            String(type),
+            String(parentType),
+          ]);
+        },
+      }),
+    );
+
+    expect(visited).to.deep.equal([
+      // Everything within ObjectValue should have type: undefined since the
+      // contents of custom scalars are not part of the GraphQL type system.
+      // getParentInputType() continues to report the closest enclosing valid
+      // input type even after traversal leaves the GraphQL input type system.
+      ['enter', 'ObjectValue', null, 'GeoPoint', 'undefined'],
+      ['enter', 'ObjectField', null, 'undefined', 'GeoPoint'],
+      ['enter', 'Name', 'x', 'undefined', 'GeoPoint'],
+      ['leave', 'Name', 'x', 'undefined', 'GeoPoint'],
+      ['enter', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['leave', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['leave', 'ObjectField', null, 'undefined', 'GeoPoint'],
+      ['enter', 'ObjectField', null, 'undefined', 'GeoPoint'],
+      ['enter', 'Name', 'y', 'undefined', 'GeoPoint'],
+      ['leave', 'Name', 'y', 'undefined', 'GeoPoint'],
+      ['enter', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['leave', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['leave', 'ObjectField', null, 'undefined', 'GeoPoint'],
+      ['leave', 'ObjectValue', null, 'GeoPoint', 'undefined'],
+    ]);
+  });
+
+  it('supports traversals of list literals in custom scalar positions', () => {
+    const schema = buildSchema(`
+      scalar GeoPoint
+    `);
+    const ast = parseValue('[4.0, 2.0]');
+    const scalarType = schema.getType('GeoPoint');
+    assert(scalarType != null);
+
+    const typeInfo = new TypeInfo(schema, scalarType);
+
+    const visited: Array<any> = [];
+    visit(
+      ast,
+      visitWithTypeInfo(typeInfo, {
+        enter(node) {
+          const type = typeInfo.getInputType();
+          const parentType = typeInfo.getParentInputType();
+          visited.push([
+            'enter',
+            node.kind,
+            node.kind === 'Name' ? node.value : null,
+            String(type),
+            String(parentType),
+          ]);
+        },
+        leave(node) {
+          const type = typeInfo.getInputType();
+          const parentType = typeInfo.getParentInputType();
+          visited.push([
+            'leave',
+            node.kind,
+            node.kind === 'Name' ? node.value : null,
+            String(type),
+            String(parentType),
+          ]);
+        },
+      }),
+    );
+
+    expect(visited).to.deep.equal([
+      // Everything including ListValue should have type: undefined since the
+      // contents of custom scalars are not part of the GraphQL type system.
+      // ListValues carry the item type, so the item type is also undefined.
+      // getParentInputType() continues to report the closest enclosing valid
+      // input type even after traversal leaves the GraphQL input type system.
+      ['enter', 'ListValue', null, 'undefined', 'GeoPoint'],
+      ['enter', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['leave', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['enter', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['leave', 'FloatValue', null, 'undefined', 'GeoPoint'],
+      ['leave', 'ListValue', null, 'undefined', 'GeoPoint'],
+    ]);
+  });
+
   it('supports traversals of fragment arguments', () => {
     const typeInfo = new TypeInfo(testSchema);
 
diff --git a/src/validation/ValidationContext.ts b/src/validation/ValidationContext.ts
index 83f5823c5b..5c2f86225b 100644
--- a/src/validation/ValidationContext.ts
+++ b/src/validation/ValidationContext.ts
@@ -285,6 +285,8 @@ export class ValidationContext extends ASTValidationContext {
     return this._typeInfo.getInputType();
   }
 
+  // Note: continues to expose the closest enclosing valid input type if
+  // traversal descends into syntax with no corresponding GraphQL input type.
   getParentInputType(): Maybe<GraphQLInputType> {
     return this._typeInfo.getParentInputType();
   }
diff --git a/src/validation/__tests__/VariablesInAllowedPositionRule-test.ts b/src/validation/__tests__/VariablesInAllowedPositionRule-test.ts
index f1396e9186..362b0d9195 100644
--- a/src/validation/__tests__/VariablesInAllowedPositionRule-test.ts
+++ b/src/validation/__tests__/VariablesInAllowedPositionRule-test.ts
@@ -534,3 +534,23 @@ describe('Validates OneOf Input Objects', () => {
     ]);
   });
 });
+
+describe('Non-specified behavior of variables within custom scalars', () => {
+  it('Allows using variables inside object literal in custom scalar', () => {
+    expectValid(`
+      query Query($x: Float) {
+        dog {
+          distanceFrom(loc: {x: $x, y: 10.0})
+        }
+      }`);
+  });
+
+  it('Allows using variables inside list literal in custom scalar', () => {
+    expectValid(`
+      query Query($x: Float) {
+        dog {
+          distanceFrom(loc: [$x, 10.0])
+        }
+      }`);
+  });
+});
diff --git a/src/validation/__tests__/harness.ts b/src/validation/__tests__/harness.ts
index cb0c424a0e..c10d5f3e13 100644
--- a/src/validation/__tests__/harness.ts
+++ b/src/validation/__tests__/harness.ts
@@ -36,6 +36,8 @@ export const testSchema: GraphQLSchema = buildSchema(`
     DOWN
   }
 
+  scalar GeoPoint
+
   type Dog implements Pet & Mammal & Canine {
     name(surname: Boolean): String
     nickname: String
@@ -44,6 +46,7 @@ export const testSchema: GraphQLSchema = buildSchema(`
     doesKnowCommand(dogCommand: DogCommand): Boolean
     isHouseTrained(atOtherHomes: Boolean = true): Boolean
     isAtLocation(x: Int, y: Int): Boolean
+    distanceFrom(loc: GeoPoint): Float
     mother: Dog
     father: Dog
   }
