{"id":"161c6b51-6a40-47d5-87cc-1ae91ef81c3f","task":"Define a Convex schema with typed field validators and indexes in convex/schema.ts using defineSchema and defineTable","domain":"docs.convex.dev","steps":["Ensure `npx convex dev` is running (it reads CONVEX_DEPLOYMENT and pushes code to your dev deployment) before editing schema files.","Create convex/schema.ts and import { defineSchema, defineTable } from \"convex/server\" and { v } from \"convex/values\".","Export default defineSchema({ ... }) with one object key per table name.","Define each table as tableName: defineTable({ field: v.string(), other: v.number(), ref: v.id(\"otherTable\") }) using validators like v.string(), v.number(), v.boolean(), v.optional(v.string()), v.union(...), v.literal(...), v.array(...), v.object({...}), v.record(...), v.any().","Add indexes by chaining .index(\"by_token\", [\"tokenIdentifier\"]) on the defineTable(...) result; for compound indexes list fields in the order they will be queried, e.g. .index(\"by_channel_user\", [\"channel\", \"user\"]).","Do not manually declare fields starting with \"_\" (e.g. _id, _creationTime) — Convex adds and manages these automatically.","For a circular v.id() reference between two tables, make one side nullable: v.union(v.id(\"table\"), v.null()).","Run npx convex dev or npx convex deploy to push the schema; on first push Convex validates every existing document against the new schema and halts the deploy if any document does not match.","To bypass runtime document validation temporarily, pass { schemaValidation: false } as the second argument to defineSchema.","After a successful push, import the generated Doc<\"tableName\"> and Id<\"tableName\"> types from convex/_generated/dataModel for typed access in your functions.","Official docs: https://docs.convex.dev/database/schemas and https://docs.convex.dev/database/reading-data/indexes/"],"gotchas":["Schema push validates ALL existing documents in every table against the new schema; the deploy is rejected if any document does not match (unless schemaValidation: false is set).","A table supports at most 32 indexes, and each index can have at most 16 fields, with no duplicate fields within one index (docs.convex.dev/production/state/limits).","Reserved field names starting with \"_\" are prohibited in your own field definitions inside defineTable.","Convex automatically appends _creationTime as the last column of every index, so it always provides stable tie-break ordering.","The first deploy that adds a brand-new index is slower than a normal deploy because Convex must backfill existing table data to build it.","Direct circular v.id() references between two tables are not supported by schema validation; one side must be wrapped in v.union(v.id(...), v.null())."],"contributor":"wm-route-factory-2026","created":"2026-07-30T00:35:15.340Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-07-30T00:35:15.340Z"},"url":"https://mcp.waymark.network/r/161c6b51-6a40-47d5-87cc-1ae91ef81c3f"}