Index: src/wp-admin/includes/upgrade.php
--- src/wp-admin/includes/upgrade.php
+++ src/wp-admin/includes/upgrade.php
@@ -886,6 +886,10 @@
 		upgrade_682();
 	}
 
+	if ( $wp_current_db_version < 60445 ) {
+		upgrade_690();
+	}
+
 	maybe_disable_link_manager();
 
 	maybe_disable_automattic_widgets();
@@ -2481,6 +2485,23 @@
 }
 
 /**
+ * Executes changes made in WordPress 6.9.0.
+ *
+ * @ignore
+ * @since 6.9.0
+ *
+ * @global int $wp_current_db_version Current database version.
+ */
+function upgrade_690() {
+	global $wp_current_db_version;
+
+	// Getting the cron array will automatically update it to version 3.
+	if ( $wp_current_db_version < 60445 ) {
+		_get_cron_array();
+	}
+}
+
+/**
  * Executes network-level upgrade routines.
  *
  * @since 3.0.0
Index: src/wp-includes/cron.php
--- src/wp-includes/cron.php
+++ src/wp-includes/cron.php
@@ -49,6 +49,12 @@
 		return false;
 	}
 
+	// Make sure args parameter is an array.
+	if ( ! is_array( $args ) ) {
+		_doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '6.9.0' );
+		$args = _cron_cast_to_array_helper( $args );
+	}
+
 	$event = (object) array(
 		'hook'      => $hook,
 		'timestamp' => $timestamp,
@@ -244,6 +250,12 @@
 		return false;
 	}
 
+	// Make sure args parameter is an array.
+	if ( ! is_array( $args ) ) {
+		_doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '6.9.0' );
+		$args = _cron_cast_to_array_helper( $args );
+	}
+
 	$schedules = wp_get_schedules();
 
 	if ( ! isset( $schedules[ $recurrence ] ) ) {
@@ -350,6 +362,12 @@
 		return false;
 	}
 
+	// Make sure args parameter is an array.
+	if ( ! is_array( $args ) ) {
+		_doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '6.9.0' );
+		$args = _cron_cast_to_array_helper( $args );
+	}
+
 	$schedules = wp_get_schedules();
 	$interval  = 0;
 
@@ -472,6 +490,12 @@
 		return false;
 	}
 
+	// Make sure args parameter is an array.
+	if ( ! is_array( $args ) ) {
+		_doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '6.9.0' );
+		$args = _cron_cast_to_array_helper( $args );
+	}
+
 	/**
 	 * Filter to override unscheduling of events.
 	 *
@@ -782,6 +806,12 @@
 		return false;
 	}
 
+	// Make sure args parameter is an array.
+	if ( ! is_array( $args ) ) {
+		_doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '6.9.0' );
+		$args = _cron_cast_to_array_helper( $args );
+	}
+
 	$key = md5( serialize( $args ) );
 
 	if ( ! $timestamp ) {
@@ -830,6 +860,12 @@
  * @return int|false The Unix timestamp (UTC) of the next time the event will occur. False if the event doesn't exist.
  */
 function wp_next_scheduled( $hook, $args = array() ) {
+	// Make sure args parameter is an array.
+	if ( ! is_array( $args ) ) {
+		_doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '6.9.0' );
+		$args = _cron_cast_to_array_helper( $args );
+	}
+
 	$next_event = wp_get_scheduled_event( $hook, $args );
 
 	if ( ! $next_event ) {
@@ -1231,7 +1267,7 @@
 		return array();
 	}
 
-	if ( ! isset( $cron['version'] ) ) {
+	if ( ! isset( $cron['version'] ) || $cron['version'] < 3 ) {
 		$cron = _upgrade_cron_array( $cron );
 	}
 
@@ -1258,7 +1294,7 @@
 		$cron = array();
 	}
 
-	$cron['version'] = 2;
+	$cron['version'] = 3;
 
 	$result = update_option( 'cron', $cron, true );
 
@@ -1284,23 +1320,39 @@
  * @return array An upgraded cron info array.
  */
 function _upgrade_cron_array( $cron ) {
-	if ( isset( $cron['version'] ) && 2 === $cron['version'] ) {
+	if ( isset( $cron['version'] ) && 3 === $cron['version'] ) {
 		return $cron;
 	}
 
 	$new_cron = array();
 
 	foreach ( (array) $cron as $timestamp => $hooks ) {
-		foreach ( (array) $hooks as $hook => $args ) {
-			$key = md5( serialize( $args['args'] ) );
-
-			$new_cron[ $timestamp ][ $hook ][ $key ] = $args;
+		foreach ( (array) $hooks as $hook => $event ) {
+			$event['args']                           = _cron_cast_to_array_helper( $event );
+			$key                                     = md5( serialize( $event['args'] ) );
+			$new_cron[ $timestamp ][ $hook ][ $key ] = $event;
 		}
 	}
 
-	$new_cron['version'] = 2;
+	$new_cron['version'] = 3;
 
 	update_option( 'cron', $new_cron, true );
 
 	return $new_cron;
 }
+
+/**
+ * Compatibility function for consistent casting to array of cron arguments.
+ *
+ * @since 6.9.0
+ * @access private
+ *
+ * @param mixed $args Cron arguments.
+ * @return array
+ */
+function _cron_cast_to_array_helper( $args ) {
+	if ( is_object( $args ) ) {
+		return array( $args );
+	}
+	return (array) $args;
+}
Index: src/wp-includes/version.php
--- src/wp-includes/version.php
+++ src/wp-includes/version.php
@@ -23,7 +23,7 @@
  *
  * @global int $wp_db_version
  */
-$wp_db_version = 60421;
+$wp_db_version = 60445;
 
 /**
  * Holds the TinyMCE version.
Index: tests/phpunit/tests/cron.php
--- tests/phpunit/tests/cron.php
+++ tests/phpunit/tests/cron.php
@@ -342,6 +342,70 @@
 	}
 
 	/**
+	 * Ensure cron events created without arguments as an array can be unscheduled.
+	 *
+	 * @ticket 34913
+	 *
+	 * @dataProvider data_clear_schedule_non_array_args
+	 *
+	 * @expectedDeprecated wp_clear_scheduled_hook
+	 * @expectedIncorrectUsage wp_schedule_single_event
+	 * @expectedIncorrectUsage wp_next_scheduled
+	 */
+	function test_clear_schedule_non_array_args( $args ) {
+		$hook = __FUNCTION__;
+		$timestamp = strtotime('+1 hour' );
+
+		// Schedule event with non-array arguments.
+		wp_schedule_single_event( $timestamp, $hook, $args );
+
+		// Make sure it's returned by wp_next_scheduled().
+		$this->assertEquals( $timestamp, wp_next_scheduled( $hook, $args ) );
+
+		// Make sure it was converted to an array.
+		$this->assertEquals( $timestamp, wp_next_scheduled( $hook, array( $args ) ) );
+
+		// Clear the schedule and make sure it's gone.
+		wp_clear_scheduled_hook( $hook, $args );
+		$this->assertFalse( wp_next_scheduled( $hook, $args ) );
+		$this->assertFalse( wp_next_scheduled( $hook, array( $args ) ) );
+	}
+
+	/**
+	 * Data provider for test_clear_schedule_non_array_args.
+	 *
+	 * @return array {
+	 *     @type array $0... {
+	 *         @type mixed $0 Cron arguments.
+	 *     }
+	 * }
+	 */
+	function data_clear_schedule_non_array_args() {
+		return array(
+			// Boolean
+			array( true ),
+
+			// Integer
+			array( 34913 ),
+
+			// Float
+			array( 34.913 ),
+
+			// String
+			array( 'Ticket 34913' ),
+
+			// stdClass
+			array(
+				(object) array(
+					'a' => 'Ticket 34913',
+					'b' => 34913,
+					'c' => false,
+				),
+			),
+		);
+	}
+
+	/**
 	 * @ticket 6966
 	 *
 	 * @covers ::wp_schedule_single_event
