{"record":{"id":"59143e136171eb88","repo":"clockworklabs/SpacetimeDB","slug":"environment-name-enum-cases-must-have-names","errorCode":null,"errorMessage":"Environment '${name}' enum cases must have names","messagePattern":"Environment '(.+?)' enum cases must have names","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/server/environment.ts","lineNumber":73,"sourceCode":"      ty = { tag: 'String' };\n    } else {\n      const type: AlgebraicType = inner?.algebraicType;\n      if (type?.tag !== 'Sum' || !('variants' in inner)) {\n        throw new TypeError(\n          `Environment '${name}' must be a string or simple enum`\n        );\n      }\n      const values = type.value.variants.map(variant => {\n        if (\n          variant.algebraicType.tag !== 'Product' ||\n          variant.algebraicType.value.elements.length !== 0\n        ) {\n          throw new TypeError(\n            `Environment '${name}' cannot use an enum payload`\n          );\n        }\n        if (typeof variant.name !== 'string')\n          throw new TypeError(\n            `Environment '${name}' enum cases must have names`\n          );\n        if (bytes.encode(variant.name).length > MAX_ENV_VALUE_BYTES)\n          throw new TypeError(`Environment '${name}' literal is too long`);\n        return variant.name;\n      });\n      if (values.length === 0 || new Set(values).size !== values.length)\n        throw new TypeError(\n          `Environment '${name}' needs a nonempty literal union`\n        );\n      ty =\n        values.length === 1\n          ? { tag: 'StringLiteral', value: values[0]! }\n          : { tag: 'Union', value: values };\n    }\n    return { name, ty, optional };\n  });\n}","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/bindings-typescript/src/server/environment.ts#L55-L91","documentation":"Every enum variant used as an environment variable must have a string name, because that name becomes the literal value written into the environment. A variant whose name is missing or not a string cannot be encoded and triggers this TypeError.","triggerScenarios":"Building an enum type whose variant.name is undefined or non-string (e.g. a programmatically constructed AlgebraicType variant lacking a name) and using it as an env var.","commonSituations":"Hand-rolling AlgebraicTypeSum variants instead of using the enum builder; refactoring codegen that dropped variant names.","solutions":["Use the enum builder API so every variant gets a name","Ensure each variant object passed to the sum type has a string name field","Inspect the constructed AlgebraicType and add missing variant names"],"exampleFix":"// before\nvariants: [{ algebraicType: productType() }]\n// after\nvariants: [{ name: 'Enabled', algebraicType: productType() }]","handlingStrategy":"validation","validationCode":"function assertVariantNamesNamed(ty) {\n  for (const v of ty.algebraicType.value.variants) {\n    if (typeof v.name !== 'string') throw new TypeError('Every enum variant must have a string name');\n  }\n}","typeGuard":"const hasNamedVariants = (ty): ty is { algebraicType: { tag: 'Sum'; value: { variants: { name: string }[] } } } =>\n  ty?.algebraicType?.tag === 'Sum' && ty.algebraicType.value.variants.every(v => typeof v.name === 'string');","tryCatchPattern":null,"preventionTips":["Construct enums via the builder API, not raw AlgebraicType objects","Add a test asserting every variant has a name","Review hand-built sum types for missing name fields"],"tags":["environment","enum","typescript"],"backgroundTag":"invalid-enum-value","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-09-20T12:15:59.611Z","contentChangedAt":"2026-09-20T12:15:59.611Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}