diff --git src/wp-includes/plugin.php src/wp-includes/plugin.php
index ea5832a..bfa5f9d 100644
--- src/wp-includes/plugin.php
+++ src/wp-includes/plugin.php
@@ -107,7 +107,23 @@ function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1
 function has_filter($tag, $function_to_check = false) {
 	global $wp_filter;
 
-	$has = !empty($wp_filter[$tag]);
+	$has = ! empty( $wp_filter[ $tag ] );
+
+	// Make sure at least one priority has a filter callback
+	if ( $has ) {
+		$exists = false;
+		foreach ( $wp_filter[ $tag ] as $callbacks ) {
+			if ( ! empty( $callbacks ) ) {
+				$exists = true;
+				break;
+			}
+		}
+
+		if ( ! $exists ) {
+			$has = false;
+		}
+	}
+
 	if ( false === $function_to_check || false == $has )
 		return $has;
 
diff --git tests/phpunit/tests/filters.php tests/phpunit/tests/filters.php
index 0f6d00a..34fdf56 100644
--- tests/phpunit/tests/filters.php
+++ tests/phpunit/tests/filters.php
@@ -267,4 +267,30 @@ class Tests_Filters extends WP_UnitTestCase {
 		$this->assertEquals( 1, $b->get_call_count(), 'priority 12 filters should run after priority 10 empties itself and priority 11 runs' );
 		$this->assertEquals( $result, $tag . '_append_append', 'priority 11 and 12 filters should run after priority 10 empties itself' );
 	}
+
+	/**
+	 * @ticket 29070
+	 */
+	function test_has_filter_after_remove_all_filters() {
+		$a = new MockAction();
+		$tag = rand_str();
+		$val = rand_str();
+
+		// No priority
+		add_filter( $tag, array( $a, 'filter' ), 11 );
+		add_filter( $tag, array( $a, 'filter' ), 12 );
+		$this->assertTrue( has_filter( $tag ) );
+
+		remove_all_filters( $tag );
+		$this->assertFalse( has_filter( $tag ) );
+
+		// Remove priorities one at a time
+		add_filter( $tag, array( $a, 'filter' ), 11 );
+		add_filter( $tag, array( $a, 'filter' ), 12 );
+		$this->assertTrue( has_filter( $tag ) );
+
+		remove_all_filters( $tag, 11 );
+		remove_all_filters( $tag, 12 );
+		$this->assertFalse( has_filter( $tag ) );
+	}
 }
