honojs/hono · error · Error

style sheet not found

Error message

style sheet not found

What it means

hono/jsx/dom/css implements CSS Modules by inserting rules into a shared style sheet that must exist in the document. insertRule looks up the style element via findStyleSheet; if none is found synchronously it retries on a microtask, and throws if the sheet still cannot be found — typically because the code runs where no style element/document exists (e.g. SSR or a stripped head).

Source

Thrown at src/jsx/dom/css.ts:97

  const findStyleSheet = (): [CSSStyleSheet, Set<string>] | [] => {
    if (!styleSheet) {
      styleSheet = document.querySelector<HTMLStyleElement>(`style#${id}`)
        ?.sheet as CSSStyleSheet | null
      if (styleSheet) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        ;(styleSheet as any).addedStyles = new Set<string>()
      }
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return styleSheet ? [styleSheet, (styleSheet as any).addedStyles] : []
  }

  const insertRule = (className: string, styleString: string) => {
    const [sheet, addedStyles] = findStyleSheet()
    if (!sheet || !addedStyles) {
      Promise.resolve().then(() => {
        if (!findStyleSheet()[0]) {
          throw new Error('style sheet not found')
        }
        insertRule(className, styleString)
      })
      return
    }

    if (!addedStyles.has(className)) {
      addedStyles.add(className)
      ;(className.startsWith(PSEUDO_GLOBAL_SELECTOR)
        ? splitRule(styleString)
        : [`${className[0] === '@' ? '' : '.'}${className}{${styleString}}`]
      ).forEach((rule) => {
        sheet.insertRule(rule, sheet.cssRules.length)
      })
    }
  }

  const cssObject = {

View on GitHub (pinned to e2740d5a1b)

Solutions

  1. Ensure the hono/jsx style-sheet style element is present in the document before rendering components that use CSS modules
  2. Avoid importing .module.css or triggering insertRule during SSR; restrict CSS-module usage to client-rendered code paths
  3. If you remove/replace style elements manually, re-create one (the expected style element) or re-mount before rendering

Example fix

// before
// SSR path imports component that uses styles from './Button.module.css'
import styles from './Button.module.css'
// after
let styles = { btn: 'fallback-btn-class' }
if (typeof document !== 'undefined') {
  styles = (await import('./Button.module.css')).default
}
Defensive patterns

Strategy: type-guard

Validate before calling

const canUseCssModules =
  typeof document !== 'undefined' &&
  !!document.querySelector('style')

Type guard

const hasStyleSheet = (): boolean => typeof document !== 'undefined' && !!findStyleSheetLike()

Try / catch

try {
  element.classList.add(styles.btn)
} catch (e) {
  if (e instanceof Error && /style sheet not found/.test(e.message)) {
    // fall back to a static class name
  }
}

Prevention

When it happens

Trigger: Importing a CSS module (e.g. `import styles from './x.module.css'`) and using its class names in a context where the injected <style> element is absent — server-side rendering, a document whose style element was removed, or calling css APIs before the sheet helper has installed the element.

Common situations: Running hono/jsx DOM components during SSR/build where document is unavailable; third-party code or cleanup logic removing the style tag; timing issues where the sheet is queried after the element was detached.

Related errors


AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28). Data as JSON: /api/errors/987d2acf3a5ebb2f. Report an issue: GitHub.