{"record":{"id":"b78e271ca4b01877","repo":"clockworklabs/SpacetimeDB","slug":"environment-name-needs-a-nonempty-literal-union","errorCode":null,"errorMessage":"Environment '${name}' needs a nonempty literal union","messagePattern":"Environment '(.+?)' needs a nonempty literal union","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/server/environment.ts","lineNumber":81,"sourceCode":"      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}\n","sourceCodeStart":63,"sourceCodeEnd":92,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/bindings-typescript/src/server/environment.ts#L63-L92","documentation":"An environment enum must expose at least one variant and all variant names must be distinct, because the set of names becomes the allowed literal union for the variable. An empty variant list or duplicate names would produce an empty or ambiguous union, so it is rejected.","triggerScenarios":"Building an enum with zero variants, or an enum with two variants sharing the same name, then declaring it as an environment variable.","commonSituations":"Programmatically generating variant lists where an empty filter yields no cases; duplicated case names from string concatenation in generated code.","solutions":["Add at least one variant to the enum","Ensure all variant names are unique","Deduplicate names before constructing the type"],"exampleFix":"// before\nenum Flags { On, On } // duplicate\n// after\nenum Flags { On, Off }","handlingStrategy":"validation","validationCode":"function assertDistinctNonemptyVariants(ty) {\n  const names = ty.algebraicType.value.variants.map(v => v.name);\n  if (names.length === 0 || new Set(names).size !== names.length) {\n    throw new TypeError('Enum must have a nonempty, distinct set of variant names');\n  }\n}","typeGuard":"const isNonemptyDistinctUnion = (names: string[]): boolean => names.length > 0 && new Set(names).size === names.length;","tryCatchPattern":"try {\n  environmentDeclarations(schema);\n} catch (e) {\n  if (e instanceof TypeError && /nonempty literal union/.test(e.message)) {\n    console.error('Enum for env var is empty or has duplicate cases');\n  } else throw e;\n}","preventionTips":["Never emit enums with zero variants","Deduplicate generated case names","Add a schema test rejecting duplicate variant names"],"tags":["environment","enum","validation","typescript"],"backgroundTag":"empty-required-field","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"}