{"record":{"id":"ed90ef8bb40929d8","repo":"clockworklabs/SpacetimeDB","slug":"when-providing-a-name-you-must-also-provide-the-v","errorCode":null,"errorMessage":"When providing a name, you must also provide the variants object or array.","messagePattern":"When providing a name, you must also provide the variants object or array\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/lib/type_builders.ts","lineNumber":3741,"sourceCode":"  /**\n   * Creates a full sum type, where each case can have a payload.\n   * Each value in the object must be a {@link TypeBuilder}.\n   *\n   * Example:\n   * ```ts\n   * t.enum(\"Result\", { Ok: t.unit(), Err: t.string() });\n   * ```\n   */\n  <Obj extends VariantsObj>(name: string, obj: Obj): SumBuilder<Obj>;\n}\n\nconst enumImpl = ((nameOrObj: any, maybeObj?: any) => {\n  let obj: any = nameOrObj;\n  let name: string | undefined = undefined;\n\n  if (typeof nameOrObj === 'string') {\n    if (!maybeObj) {\n      throw new TypeError(\n        'When providing a name, you must also provide the variants object or array.'\n      );\n    }\n    obj = maybeObj;\n    name = nameOrObj;\n  }\n\n  // Simple sum (array form)\n  if (Array.isArray(obj)) {\n    const simpleVariantsObj: Record<string, UnitBuilder> = {};\n    for (const variant of obj) {\n      simpleVariantsObj[variant] = new UnitBuilder();\n    }\n    return new SimpleSumBuilderImpl(simpleVariantsObj, name);\n  }\n\n  // Regular sum (object form)\n  return new SumBuilder(obj, name);","sourceCodeStart":3723,"sourceCodeEnd":3759,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings-typescript/src/lib/type_builders.ts#L3723-L3759","documentation":"In SpacetimeDB 2.x, #[spacetimedb::table] requires an accessor: the snake_case identifier used for the generated module accessor and view/query traits. It is separate from name, which is optional and only sets the on-chain table name. When the argument list yields no accessor — including the 1.x-style name = \"...\" only form — the derive fails with a template showing the expected accessor for the struct.","triggerScenarios":"#[spacetimedb::table] with no arguments, or #[spacetimedb::table(name = \"player\")] with no accessor = ... argument.","commonSituations":"Upgrading a 1.x module where name = \"...\" used to be sufficient; writing new tables from pre-2.0 docs or tutorials; renaming attributes during cleanup.","solutions":["Add the accessor argument with an identifier (not a string): #[spacetimedb::table(accessor = player)].","Migrating from 1.x: replace name = \"player\" with accessor = player; keep name = \"...\" only if you also need a custom on-chain table name.","Choose the identifier your code will reference (ctx.player, player::view(), ...)."],"exampleFix":"// before (1.x style)\n#[spacetimedb::table(name = \"player\")]\npub struct Player { ... }\n\n// after\n#[spacetimedb::table(accessor = player)]\npub struct Player { ... }\n// optional on-chain name stays separate:\n#[spacetimedb::table(accessor = player, name = \"player\")]","handlingStrategy":"validation","validationCode":"# CI check: 1.x-style tables without an accessor\nrg -n 'spacetimedb::table\\(\\s*\\)|spacetimedb::table\\(\\s*name' src/ && exit 1 || true","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When upgrading to SpacetimeDB 2.x, mechanically rewrite name = \"x\" to accessor = x in table attributes.","New tables: always start from #[spacetimedb::table(accessor = my_table)] and add name only for a custom on-chain name.","Update project templates and docs so generated code includes the accessor."],"tags":["spacetimedb","proc-macro","table","migration","compile-time"],"backgroundTag":"missing-required-attribute","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}