clockworklabs/SpacetimeDB · error · TypeError

Environment ' ' must be a string or simple enum

Error message

Environment '${name}' must be a string or simple enum

What it means

Environment variables may only be strings or simple enums (string-literal unions). environmentDeclarations() inspects the builder's AlgebraicType and requires a Sum type with named variants; anything else (ints, options of other types, plain products, structs) is rejected because only string-like values can be mapped to process environment values.

Solutions

  1. Use StringBuilder (str) for the variable
  2. Use an enum builder whose variants are all unit (no payloads)
  3. Remove the unsupported type from the environment schema and read it another way

Example fix

// before
const schema = { port: u32 };
// after
const schema = { port: str }; // or an enum of allowed values
Defensive patterns

Strategy: validation

Validate before calling

function assertStringOrEnumBuilder(v) {
  if (!(v instanceof StringBuilder) && !(v instanceof OptionBuilder && v.value instanceof Object && v.value.algebraicType?.tag === 'Sum')) {
    throw new TypeError('Env var must be a string or simple enum');
  }
}

Try / catch

try {
  environmentDeclarations(schema);
} catch (e) {
  if (e instanceof TypeError && /must be a string or simple enum/.test(e.message)) {
    console.error('Env var must be str or a unit-only enum:', e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a builder whose inner algebraicType is not a Sum (e.g. a u32 builder, a struct builder, or undefined inner) as an environment variable value in the schema.

Common situations: Trying to expose a numeric port or a struct-typed config object as an env var; forgetting that only strings and enum builders are supported.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20). Data as JSON: /api/errors/15446ff3173e4f63. Report an issue: GitHub.

Appendix: source

Thrown at crates/bindings-typescript/src/server/environment.ts:59

  if (entries.length > MAX_ENV_VARS)
    throw new TypeError('Too many environment declarations');
  const bytes = new TextEncoder();
  return entries.map(([name, definition]) => {
    if (
      !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) ||
      bytes.encode(name).length > MAX_ENV_KEY_BYTES
    ) {
      throw new TypeError('Invalid environment declaration name');
    }
    const optional = definition instanceof OptionBuilder;
    const inner = optional ? definition.value : definition;
    let ty: EnvVarType;
    if (inner instanceof StringBuilder) {
      ty = { tag: 'String' };
    } else {
      const type: AlgebraicType = inner?.algebraicType;
      if (type?.tag !== 'Sum' || !('variants' in inner)) {
        throw new TypeError(
          `Environment '${name}' must be a string or simple enum`
        );
      }
      const values = type.value.variants.map(variant => {
        if (
          variant.algebraicType.tag !== 'Product' ||
          variant.algebraicType.value.elements.length !== 0
        ) {
          throw new TypeError(
            `Environment '${name}' cannot use an enum payload`
          );
        }
        if (typeof variant.name !== 'string')
          throw new TypeError(
            `Environment '${name}' enum cases must have names`
          );
        if (bytes.encode(variant.name).length > MAX_ENV_VALUE_BYTES)
          throw new TypeError(`Environment '${name}' literal is too long`);

View on GitHub (pinned to eddf9f5014)