diff --git includes/theme.inc includes/theme.inc
index a9cca84..67c867b 100644
--- includes/theme.inc
+++ includes/theme.inc
@@ -764,6 +764,11 @@ function list_themes($refresh = FALSE) {
  */
 function theme($hook, $variables = array()) {
   static $hooks = NULL;
+
+  if (!module_load_all(NULL) && !defined('MAINTENANCE_MODE')) {
+    throw new Exception(t('theme() may not be called until all modules are loaded.'));
+  }
+
   if (!isset($hooks)) {
     drupal_theme_initialize();
     $hooks = theme_get_registry();
diff --git modules/simpletest/tests/theme.test modules/simpletest/tests/theme.test
index 8a0ead9..b3bf93a 100644
--- modules/simpletest/tests/theme.test
+++ modules/simpletest/tests/theme.test
@@ -44,7 +44,7 @@ class ThemeUnitTest extends DrupalWebTestCase {
     $suggestions = theme_get_suggestions($args, 'page');
     $this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1'), t('Removed invalid \\0 from suggestions'));
   }
-  
+
   /**
   * Preprocess functions for the base hook should run even for suggestion implementations.
   */
@@ -148,3 +148,30 @@ class ThemeItemListUnitTest extends DrupalWebTestCase {
     $this->assertIdentical($expected, $output, 'Nested list is rendered correctly.');
   }
 }
+
+/**
+ * Functional test for initialization of the theme system in hook_init().
+ */
+class ThemeHookInitUnitTest extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Theme initialization in hook_init()',
+      'description' => 'Tests that the theme system can be correctly initialized in hook_init().',
+      'group' => 'Theme',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('theme_test');
+    variable_set('theme_default', 'garland');
+  }
+
+  /**
+   * Test that the theme system can generate output when called by hook_init().
+   */
+  function testThemeInitializationHookInit() {
+    $this->drupalGet('theme-test/hook-init');
+    $this->assertRaw('Themed output generated in hook_init()', t('Themed output generated in hook_init() correctly appears on the page.'));
+    $this->assertRaw('garland/style.css', t("The default theme's CSS appears on the page when the theme system is initialized in hook_init()."));
+  }
+}
diff --git modules/simpletest/tests/theme_test.module modules/simpletest/tests/theme_test.module
index 6270c1d..d83108a 100644
--- modules/simpletest/tests/theme_test.module
+++ modules/simpletest/tests/theme_test.module
@@ -12,11 +12,37 @@ function theme_test_menu() {
     'theme callback' => '_theme_custom_theme',
     'type' => MENU_CALLBACK,
   );
-
+  $items['theme-test/hook-init'] = array(
+    'page callback' => 'theme_test_hook_init_page_callback',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
 /**
+ * Implement hook_init().
+ */
+function theme_test_init() {
+  // First, flush all caches to ensure that the theme registry will be rebuilt
+  // on this page request. This allows us to test a full initialization of the
+  // theme system in the code below.
+  drupal_flush_all_caches();
+  // Next, initialize the theme system by storing themed text in a global
+  // variable. We will use this later in theme_test_hook_init_page_callback()
+  // to test that even when the theme system is initialized this early, it is
+  // still capable of returning output and theming the page as a whole.
+  $GLOBALS['theme_test_output'] = theme('more_link', array('url' => url('user'), 'title' => 'Themed output generated in hook_init()'));
+}
+
+/**
+ * Menu callback for testing themed output generated in hook_init().
+ */
+function theme_test_hook_init_page_callback() {
+  return $GLOBALS['theme_test_output'];
+}
+
+/**
  * Custom theme callback.
  */
 function _theme_custom_theme() {
