-
Notifications
You must be signed in to change notification settings - Fork 98
Description
Hi!
Thanks for this project, it is revolutionary! I'm trying to understand it a bit more and have been playing with it, this is an error that I get quite often, and have been trying to track it down or find the cause of it, with not much success unfortunately 😅.
Error: View node is being updated before it is initialized
Here is the full log from the triplit server:
23:26:21 ⬅ CHANGES_ACK
23:26:21 ⚠️ ERROR: Error while processing message CHANGES
Error: View node is being updated before it is initialized
at IVM.updateViews (file:///Users/krisztianlazar/github/triplit-issue/node_modules/@triplit/cli/dist/chunk-RKJJMDSJ.js:6325:19)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
23:26:21 ⬅ ERROR CHANGES TriplitError: Triplit Error | Context: An unknown error occurred while processing your request.
23:26:22 ➡ CHANGES
23:26:22 ⬅ CHANGES_ACK
23:26:22 ⚠️ ERROR: Error while processing message CHANGES
Error: View node is being updated before it is initialized
at IVM.updateViews (file:///Users/krisztianlazar/github/triplit-issue/node_modules/@triplit/cli/dist/chunk-RKJJMDSJ.js:6325:19)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
23:26:22 ⬅ ERROR CHANGES TriplitError: Triplit Error | Context: An unknown error occurred while processing your request.
23:26:22 ➡ CHANGES
23:26:22 ⬅ CHANGES_ACK
23:26:22 ⚠️ ERROR: Error while processing message CHANGES
Error: View node is being updated before it is initialized
at IVM.updateViews (file:///Users/krisztianlazar/github/triplit-issue/node_modules/@triplit/cli/dist/chunk-RKJJMDSJ.js:6325:19)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
23:26:22 ⬅ ERROR CHANGES TriplitError: Triplit Error | Context: An unknown error occurred while processing your request.
23:26:22 ➡ CHANGES
23:26:22 ⬅ CHANGES_ACK
23:26:22 ⚠️ ERROR: Error while processing message CHANGES
Error: View node is being updated before it is initialized
at IVM.updateViews (file:///Users/krisztianlazar/github/triplit-issue/node_modules/@triplit/cli/dist/chunk-RKJJMDSJ.js:6325:19)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
23:26:22 ⬅ ERROR CHANGES TriplitError: Triplit Error | Context: An unknown error occurred while processing your request.
here is one of the CHANGES payload:
{
"type": "CHANGES",
"payload": {
"changes": {
"json": {
"metas": {
"sets": [
[
"oGdRrCGahVRjyz1QQlIOb",
{
"id": "oGdRrCGahVRjyz1QQlIOb",
"visibility": "private",
"userId": "Bn3XcKjbnhrzgdLPQopkdcvuCPHCJ8bJ"
}
]
],
"deletes": []
},
"todos": {
"sets": [
[
"5IQh6-ZtoIXddreyP46IG",
{
"id": "5IQh6-ZtoIXddreyP46IG",
"userId": "Bn3XcKjbnhrzgdLPQopkdcvuCPHCJ8bJ",
"text": "This is a dummy todo",
"completed": false,
"createdAt": "2025-08-14T21:26:22.394Z",
"updatedAt": "2025-08-14T21:26:22.394Z",
"metaId": "oGdRrCGahVRjyz1QQlIOb"
}
]
],
"deletes": []
}
},
"meta": {
"values": {
"metas.sets": [
"map"
],
"metas.deletes": [
"set"
],
"todos.sets": [
"map"
],
"todos.deletes": [
"set"
]
}
}
}
}
}I have found the following Discord conversation: https://discord.com/channels/1138467878623006720/1375318110567137332, where davey had the exact same issues that I'm running into.
Although the Discord thread does pose a solution to this issue, I'm having a hard time understanding what's actually happening, or what is the root cause of the issue.
Suppose I have the following schema:
import { or, Schema as S } from "@triplit/client";
import { authSchema } from "./auth-schema";
const isUid = ["userId", "=", "$token.sub"] as const;
/**
* Define your schema here. After:
* - Pass your schema to your Triplit client
* - Push your schema to your Triplit server with 'triplit schema push'
*
* For more information about schemas, see the docs: https://www.triplit.dev/docs/schemas
*/
export const schema = S.Collections({
...authSchema,
// this is just some dummy stuff, can be any other arbitrary type.
metas: {
schema: S.Schema({
id: S.Id(),
visibility: S.String({ enum: ["public", "private"], default: "private" }),
userId: S.String(),
}),
relationships: {
todos: S.RelationMany("todos", { where: [["metaId", "=", "$id"]] }),
},
permissions: {
authenticated: {
read: {
filter: [["userId", "=", "$token.sub"]],
},
insert: {
filter: [["userId", "=", "$token.sub"]],
},
update: {
filter: [["userId", "=", "$token.sub"]],
},
delete: {
filter: [["userId", "=", "$token.sub"]],
},
},
},
},
todos: {
schema: S.Schema({
id: S.Id(),
userId: S.String(),
text: S.String(),
completed: S.Boolean({ default: false }),
createdAt: S.Date({ default: S.Default.now() }),
updatedAt: S.Date({ default: S.Default.now() }),
metaId: S.String(),
}),
relationships: {
meta: S.RelationById("metas", "metaId"),
},
permissions: {
authenticated: {
read: {
filter: [
or([
isUid,
// ["meta.visibility", "=", "public"], // this is causing the issue
]),
],
},
insert: {
filter: [isUid],
},
update: {
filter: [isUid],
},
postUpdate: {
filter: [
isUid,
["updatedAt", ">", "$prev.updatedAt"],
["createdAt", "=", "$prev.createdAt"],
],
},
delete: {
filter: [isUid],
},
},
},
},
});I have tracked the issue down to this particular line:
["meta.visibility", "=", "public"]I also have the following dummy component that I've used for testing and trying to figure out the root cause of the issue:
"use client";
import { Button } from "@/components/ui/button";
import { triplit } from "@/triplit/client";
import { schema } from "@/triplit/schema";
import { Entity } from "@triplit/client";
import { useQuery } from "@triplit/react";
type TodoType = Entity<typeof schema, "todos">;
export default function Home() {
const { results: todos } = useQuery(triplit, triplit.query("todos"));
async function createTodo() {
const todo = await triplit.transact(async (tx) => {
const dummy = await tx.insert("metas", {
userId: triplit.vars.$token.sub,
});
const todo = await tx.insert("todos", {
completed: false,
metaId: dummy.id,
text: "This is a dummy todo",
userId: triplit.vars.$token.sub,
});
return todo;
});
}
async function deleteTodos() {
await triplit.transact(async (tx) => {
const metas = await tx.fetch(triplit.query("metas").Include("todos"));
for (const meta of metas) {
for (const todo of meta.todos) {
await tx.delete("todos", todo.id);
}
await tx.delete("metas", meta.id);
}
});
}
return (
<div>
<div className="flex gap-2">
<Button type="button" onClick={createTodo}>
Create Todo
</Button>
<Button variant="destructive" type="button" onClick={deleteTodos}>
Dummy Button
</Button>
</div>
<ul className="mt-4 space-y-2">
{todos?.map((t) => (
<li key={t.id} className="flex items-center gap-2">
<span>{t.text}</span>
{t.completed && <span className="text-green-600">(Completed)</span>}
</li>
))}
</ul>
</div>
);
}In the Discord thread it is said that:
Which is that the permission on `applications` for an authenticated user references `organization.members.userId` but neither organizations nor members actually allows anyone but the service token to read them, which is leading to a query that our subscription system is having trouble setting up a graph for
however if I'm not mistaken, in this case meta (my dummy entity) has all the necessary permissions, so does todos entity. Upon further investigating I thought maybe if I change the order of the insert or delete, ex.: insert the todo, and after that insert the meta, and vice versa for the delete. This unfortunately resulting in the issue again.
Here are my questions:
- Is there something I'm missing?
- How are these entities resolved?
- Should this be mentioned in the docs?
- What should be the order of these types of mutations when there might be a dependency between the entities being mutated?
- Is this caused by some kind of circular dependency, since both entities are referencing each other? 🤔
here is the full repro repo: https://github.com/lazakrisz/triplit-issue
main files are: https://github.com/lazakrisz/triplit-issue/blob/aa9d77a96d6236c4626fd0edbd1eae1ea8778c37/src/triplit/schema.ts#L13
https://github.com/lazakrisz/triplit-issue/blob/aa9d77a96d6236c4626fd0edbd1eae1ea8778c37/src/app/page.tsx#L11
thanks so much! 🙏