{"record":{"id":"492845f05b6694d5","repo":"clockworklabs/SpacetimeDB","slug":"e","errorCode":null,"errorMessage":"{e}","messagePattern":"\\{e\\}","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bindings/src/table.rs","lineNumber":65,"sourceCode":"    ///\n    /// The return value is the inserted row, with any auto-incrementing columns replaced with computed values.\n    /// The `insert` method always returns the inserted row,\n    /// even when the table contains no auto-incrementing columns.\n    ///\n    /// (The returned row is a copy of the row in the database.\n    /// Modifying this copy does not directly modify the database.\n    /// See [`UniqueColumn::update`] if you want to update the row.)\n    ///\n    /// May panic if inserting the row violates any constraints.\n    /// Callers which intend to handle constraint violation errors should instead use [`Self::try_insert`].\n    ///\n    /// Inserting an exact duplicate of a row already present in the table is a no-op,\n    /// as SpacetimeDB is a set-semantic database.\n    /// This is true even for tables with unique constraints;\n    /// inserting an exact duplicate of an already-present row will not panic.\n    #[track_caller]\n    fn insert(&self, row: Self::Row) -> Self::Row {\n        self.try_insert(row).unwrap_or_else(|e| panic!(\"{e}\"))\n    }\n\n    /// The error type for this table for unique constraint violations. Will either be\n    /// [`UniqueConstraintViolation`] if the table has any unique constraints, or [`Infallible`]\n    /// otherwise.\n    type UniqueConstraintViolation: MaybeError<UniqueConstraintViolation>;\n\n    /// The error type for this table for auto-increment overflows. Will either be\n    /// [`AutoIncOverflow`] if the table has any auto-incrementing columns, or [`Infallible`]\n    /// otherwise.\n    type AutoIncOverflow: MaybeError<AutoIncOverflow>;\n\n    /// Counterpart to [`Self::insert`] which allows handling failed insertions.\n    ///\n    /// For tables with constraints, this method returns an `Err` when the insertion fails rather than panicking.\n    /// For tables without any constraints, [`Self::UniqueConstraintViolation`] and [`Self::AutoIncOverflow`]\n    /// will be [`std::convert::Infallible`], and this will be a more-verbose [`Self::insert`].\n    ///","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings/src/table.rs#L47-L83","documentation":"TableHandle::insert panics with the error returned by try_insert: a UniqueConstraintViolation when the row's unique-column or primary-key value is already present on a different row, or an AutoIncOverflow when an auto-increment column exhausted its type. Exact duplicates are no-ops (set semantics) - the panic is specifically a different row reusing a unique value.","triggerScenarios":"Inserting a second row with the same #[unique]#[primary_key] value but different other fields; seeding logic running twice with fresh non-key fields; auto-inc i64 column that overflowed after ~9.2e18 inserts.","commonSituations":"Seed reducers re-run on every publish; two concurrent reducer calls inserting the same key (one transaction aborts with this panic); expecting upsert semantics from insert.","solutions":["Switch to try_insert and handle the Err(UniqueConstraintViolation) branch for expected duplicates.","If upsert is intended, use the primary key column's insert_or_update / update APIs instead of insert.","Pre-check existence via the unique column handle (ctx.db.my_table().id().find(value)) before inserting."],"exampleFix":"// before: panics when a user with this email already exists\nctx.db.user().insert(User { email, name });\n\n// after: handle the violation explicitly\nif let Err(_e) = ctx.db.user().try_insert(User { email, name }) {\n    // unique constraint violated - update instead, or return an error to the client\n}\n// or, on a primary key column: ctx.db.user().id().insert_or_update(row);","handlingStrategy":"try-catch","validationCode":"let existing = ctx.db.user().email().find(&row.email);\nif existing.is_some() {\n    // duplicate unique value - update instead of insert\n}","typeGuard":null,"tryCatchPattern":"match ctx.db.user().try_insert(row) {\n    Ok(inserted) => inserted,\n    Err(err) => {\n        // UniqueConstraintViolation or AutoIncOverflow\n        Err(reject(format!(\"duplicate: {err}\")))\n    }\n}","preventionTips":["Default to try_insert in reducer code; reserve insert() for values you have already proven unique.","Make seeding reducers idempotent (check-then-insert or try_insert).","Use insert_or_update on the primary key when upsert semantics are intended."],"tags":["rust","module","insert","unique-constraint","database"],"backgroundTag":"unique-constraint-violation","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}