{"record":{"id":"474147b42873cace","repo":"DapperLib/Dapper","slug":"type-474147","errorCode":null,"errorMessage":"type","messagePattern":"type","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Dapper/SqlMapper.Async.cs","lineNumber":215,"sourceCode":"        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"ApiDesign\", \"RS0026:Do not add multiple public overloads with optional parameters\", Justification = \"Grandfathered\")]\r\n        public static Task<dynamic?> QuerySingleOrDefaultAsync(this IDbConnection cnn, string sql, object? param = null, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null) =>\r\n            QueryRowAsync<dynamic?>(cnn, Row.SingleOrDefault, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default));\r\n\r\n        /// <summary>\r\n        /// Execute a query asynchronously using Task.\r\n        /// </summary>\r\n        /// <param name=\"cnn\">The connection to query on.</param>\r\n        /// <param name=\"type\">The type to return.</param>\r\n        /// <param name=\"sql\">The SQL to execute for the query.</param>\r\n        /// <param name=\"param\">The parameters to pass, if any.</param>\r\n        /// <param name=\"transaction\">The transaction to use, if any.</param>\r\n        /// <param name=\"commandTimeout\">The command timeout (in seconds).</param>\r\n        /// <param name=\"commandType\">The type of command to execute.</param>\r\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"type\"/> is <c>null</c>.</exception>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"ApiDesign\", \"RS0026:Do not add multiple public overloads with optional parameters\", Justification = \"Grandfathered\")]\r\n        public static Task<IEnumerable<object>> QueryAsync(this IDbConnection cnn, Type type, string sql, object? param = null, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)\r\n        {\r\n            if (type is null) throw new ArgumentNullException(nameof(type));\r\n            return QueryAsync<object>(cnn, type, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Execute a single-row query asynchronously using Task.\r\n        /// </summary>\r\n        /// <param name=\"cnn\">The connection to query on.</param>\r\n        /// <param name=\"type\">The type to return.</param>\r\n        /// <param name=\"sql\">The SQL to execute for the query.</param>\r\n        /// <param name=\"param\">The parameters to pass, if any.</param>\r\n        /// <param name=\"transaction\">The transaction to use, if any.</param>\r\n        /// <param name=\"commandTimeout\">The command timeout (in seconds).</param>\r\n        /// <param name=\"commandType\">The type of command to execute.</param>\r\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"type\"/> is <c>null</c>.</exception>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"ApiDesign\", \"RS0026:Do not add multiple public overloads with optional parameters\", Justification = \"Grandfathered\")]\r\n        public static Task<object> QueryFirstAsync(this IDbConnection cnn, Type type, string sql, object? param = null, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)\r\n        {\r\n            if (type is null) throw new ArgumentNullException(nameof(type));\r","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/DapperLib/Dapper/blob/72a54c475f75e18cb93cba0809d00a5e6e49efd9/Dapper/SqlMapper.Async.cs#L197-L233","documentation":"QueryAsync(IDbConnection, Type, ...) throws ArgumentNullException(nameof(type)) when the Type argument is null. The non-generic async overload needs a concrete type to materialize rows, so null is unrecoverable. The XML doc explicitly documents this exception. The check happens synchronously before any I/O.","triggerScenarios":"Calling cnn.QueryAsync(null, sql, ...) — e.g. passing a type resolved via Type.GetType that returned null; passing a typeof expression replaced by a variable that lost its value.","commonSituations":"Type.GetType with a wrong assembly-qualified name returning null; deserializing into a type chosen from config where the key was missing; generics erased to object where the type slot became null.","solutions":["Resolve and null-check the Type before calling QueryAsync.","Correct the assembly-qualified type name and ensure the assembly is loaded."],"exampleFix":"// before\nvar rows = await cnn.QueryAsync(Type.GetType(modelName), sql, param);\n\n// after\nvar type = Type.GetType(modelName) ?? throw new InvalidOperationException($\"Unknown type: {modelName}\");\nvar rows = await cnn.QueryAsync(type, sql, param);","handlingStrategy":"validation","validationCode":"var type = Type.GetType(modelName) ?? throw new InvalidOperationException($\"Unknown type: {modelName}\");\nvar rows = await cnn.QueryAsync(type, sql, param);","typeGuard":"static Type RequireType(Type? t) => t ?? throw new ArgumentNullException(\"type\");","tryCatchPattern":null,"preventionTips":["Null-check Type.GetType results before async query calls.","Validate all config-driven type names at startup."],"tags":["argument-null","async","query","reflection"],"backgroundTag":null,"analyzedSha":"72a54c475f75e18cb93cba0809d00a5e6e49efd9","analyzedAt":"2026-08-13T14:18:18.115Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}