Index: class-wp-export-query.php
===================================================================
--- class-wp-export-query.php	(revision 82790)
+++ class-wp-export-query.php	(working copy)
@@ -27,6 +27,8 @@
 	private $author;
 	private $category;
 
+	public $missing_parents = false;
+
 	public function __construct( $filters = array() ) {
 		$this->filters = wp_parse_args( $filters, self::$defaults );
 		$this->post_ids = $this->calculate_post_ids();
@@ -76,7 +78,11 @@
 			return array();
 		}
 		$categories = (array) get_categories( array( 'get' => 'all' ) );
+
+		$this->check_for_orphaned_terms( $categories );
+
 		$categories = self::topologically_sort_terms( $categories );
+
 		return $categories;
 	}
 
@@ -85,6 +91,9 @@
 			return array();
 		}
 		$tags = (array) get_tags( array( 'get' => 'all' ) );
+
+		$this->check_for_orphaned_terms( $tags );
+
 		return $tags;
 	}
 
@@ -94,6 +103,7 @@
 		}
 		$custom_taxonomies = get_taxonomies( array( '_builtin' => false ) );
 		$custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) );
+		$this->check_for_orphaned_terms( $custom_terms );
 		$custom_terms = self::topologically_sort_terms( $custom_terms );
 		return $custom_terms;
 	}
@@ -271,6 +281,24 @@
 		return $sorted;
 	}
 
+	private function check_for_orphaned_terms( $terms ) {
+		$term_ids = array();
+		$have_parent = array();
+
+		foreach ( $terms as $term ) {
+			$term_ids[ $term->term_id ] = true;
+			if ( $term->parent != 0 )
+				$have_parent[] = $term;
+		}
+
+		foreach ( $have_parent as $has_parent ) {
+			if ( ! isset( $term_ids[ $has_parent->parent ] ) ) {
+				$this->missing_parents = $has_parent;
+				throw new WP_Export_Term_Exception( __( 'Term is missing a parent.' ) );
+			}
+		}
+	}
+
 	private static function get_terms_for_post( $post ) {
 		$taxonomies = get_object_taxonomies( $post->post_type );
 		if ( empty( $taxonomies ) )
@@ -309,3 +337,6 @@
 
 class WP_Export_Exception extends RuntimeException {
 }
+
+class WP_Export_Term_Exception extends RuntimeException {
+}
Index: functions.export.php
===================================================================
--- functions.export.php	(revision 82790)
+++ functions.export.php	(working copy)
@@ -14,7 +14,12 @@
 	try {
 		return $writer->export();
 	} catch ( WP_Export_Exception $e ) {
-		return new WP_Error( 'wp-export-error', $e->getMessage() );
+		$message = apply_filters( 'export_error_message', $e->getMessage() );
+		wp_die( $message, __( 'Export Error' ), array( 'back_link' => true ) );
+	} catch ( WP_Export_Term_Exception $e ) {
+		do_action( 'export_term_orphaned', $export_query->missing_parents );
+		$message = apply_filters( 'export_term_error_message', $e->getMessage() );
+		wp_die( $message, __( 'Export Error' ), array( 'back_link' => true ) );
 	}
 }
 
Index: writers.php
===================================================================
--- writers.php	(revision 82790)
+++ writers.php	(working copy)
@@ -26,10 +26,15 @@
 	}
 
 	public function export() {
+		ob_start();
+		parent::export();
+		$output = ob_get_contents();
+		ob_end_clean();
+
 		header( 'Content-Description: File Transfer' );
 		header( 'Content-Disposition: attachment; filename=' . $this->file_name );
 		header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
-		parent::export();
+		echo $output;
 	}
 
 	protected function write( $xml ) {
