solidjs/solid · error · Error

getContextId cannot be used under non-hydrating context

Error message

getContextId cannot be used under non-hydrating context

What it means

On the server, sharedConfig.getContextId() returns a hydration context id derived from sharedConfig.context.count. That context only exists while Solid is inside a hydrating/render pass (createComponent/hydration). Calling getContextId outside such a pass throws because there is no context to derive an id from.

Source

Thrown at packages/solid/src/server/rendering.ts:114

      if (typeof prev !== "object" && typeof node[i] !== "object") mapped += `<!--!$-->`;
      mapped += resolveSSRNode((prev = node[i]));
    }
    return mapped;
  }
  if (t === "object") return node.t;
  if (t === "function") return resolveSSRNode(node());
  return String(node);
}

type SharedConfig = {
  context?: HydrationContext;
  getContextId(): string;
  getNextContextId(): string;
};
export const sharedConfig: SharedConfig = {
  context: undefined,
  getContextId() {
    if (!this.context) throw new Error(`getContextId cannot be used under non-hydrating context`);
    return getContextId(this.context.count);
  },
  getNextContextId() {
    if (!this.context)
      throw new Error(`getNextContextId cannot be used under non-hydrating context`);
    return getContextId(this.context.count++);
  }
};

function getContextId(count: number) {
  const num = String(count),
    len = num.length - 1;
  return sharedConfig.context!.id + (len ? String.fromCharCode(96 + len) : "") + num;
}

function setHydrateContext(context?: HydrationContext): void {
  sharedConfig.context = context;
}

View on GitHub (pinned to f47845f9cc)

Solutions

  1. Only call getContextId/getNextContextId inside the component tree during SSR or hydration
  2. Check sharedConfig.context exists before calling: if (sharedConfig.context) ...
  3. If you need ids outside rendering, generate them with your own counter or crypto.randomUUID

Example fix

// before
const id = sharedConfig.getContextId(); // outside render -> throws

// after
const id =
  sharedConfig.context
    ? sharedConfig.getContextId()
    : crypto.randomUUID();
Defensive patterns

Strategy: validation

Validate before calling

import { sharedConfig } from 'solid-js/web';
const id = sharedConfig.context ? sharedConfig.getContextId() : crypto.randomUUID();

Type guard

const hasHydrationContext = (sc: typeof sharedConfig): boolean => !!sc.context;

Try / catch

try { return sharedConfig.getContextId(); } catch (e) { if (/non-hydrating context/.test(String(e))) return crypto.randomUUID(); throw e; }

Prevention

When it happens

Trigger: Calling sharedConfig.getContextId() (directly or via APIs that use it, like certain hydration-aware components) at module scope or outside renderToString/renderToStream's component tree on the server.

Common situations: Calling hydration utilities in plain Node code; running server code outside the render lifecycle; library code assuming a hydration context that a non-hydrating entry point never sets up.

Related errors


AI-assisted analysis of solidjs/solid@f47845f9cc (2026-08-27). Data as JSON: /api/errors/9bda7f8f6e66aa20. Report an issue: GitHub.