clockworklabs/SpacetimeDB · error · TypeError
Invalid environment declaration name
Error message
Invalid environment declaration name
What it means
Each environment variable name must be a valid identifier (matching /^[A-Za-z_][A-Za-z0-9_]*$/) and fit within MAX_ENV_KEY_BYTES when UTF-8 encoded. This ensures the name can be emitted as an identifier/attribute in generated artifacts and referenced uniformly across client languages.
Solutions
- Rename the variable to match /^[A-Za-z_][A-Za-z0-9_]*$/ (letters, digits, underscore; not starting with a digit)
- Shorten the name so its UTF-8 encoding is within MAX_ENV_KEY_BYTES
- Validate names with a regex/length check before building the schema
Example fix
// before
const schema = { 'my-app-key': str };
// after
const schema = { my_app_key: str }; Defensive patterns
Strategy: validation
Validate before calling
const ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
function assertValidEnvNames(schema) {
for (const name of Object.keys(schema)) {
if (!ENV_NAME_RE.test(name) || new TextEncoder().encode(name).length > MAX_ENV_KEY_BYTES) {
throw new TypeError(`Invalid env name: ${name}`);
}
}
} Type guard
const isValidEnvName = (n: string): boolean => /^[A-Za-z_][A-Za-z0-9_]*$/.test(n) && new TextEncoder().encode(n).length <= MAX_ENV_KEY_BYTES;
Try / catch
try {
environmentDeclarations(schema);
} catch (e) {
if (e instanceof TypeError && e.message === 'Invalid environment declaration name') {
console.error('Fix env key naming (identifier chars, <= MAX_ENV_KEY_BYTES bytes)');
} else throw e;
} Prevention
- Use only SCREAMING_SNAKE_CASE identifiers for env keys
- Lint schema keys with the identifier regex in CI
- Avoid copy-pasting OS env names with hyphens or dots
When it happens
Trigger: Declaring an env var whose name starts with a digit, contains hyphens/dots/spaces, is an empty string, or whose UTF-8 length exceeds MAX_ENV_KEY_BYTES, then running module build via environmentDeclarations().
Common situations: Copy-pasting OS env names like 'MY-APP-KEY' or 'my.app.key' into the schema; using lowercase dotted names from config files; very long generated key names.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Environment ' ' cannot use an enum payload
- Environment ' ' must be a string or simple enum
- Environment ' ' needs a nonempty literal union
- Too many environment declarations
- Environment key is both supplied and removed
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20).
Data as JSON: /api/errors/cb33b43ed0b62575.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-typescript/src/server/environment.ts:49
Environment,
EnvironmentFor,
EnvironmentSchema,
} from '../lib/environment';
/** Produce metadata only. No environment value is embedded in the artifact. */
export function environmentDeclarations(
schema: EnvironmentSchema
): EnvironmentDeclaration[] {
const entries = Object.entries(schema);
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
) {View on GitHub (pinned to eddf9f5014)