CACAO Error when running local node

Hi, I can’t seem to find the Blog I originally followed which had the walk-through for this repo: GitHub - ceramicstudio/create-ceramic-app - is it possible to repost that here? I know I found it somewhere in the docs at one point, but I can’t seem to find it again.

I was trying to integrate this login button into our app and build out from there, but after a few days I’m not able to write because of this error:

[Ceramic] [2023-01-20T05:58:59.698Z] ERROR: Error: CACAO expired: Commit bagcqceravpam5dgq7vnxsyy2kr2zfoa7khvratwfape3agtqzk4lt3knr6kq of Stream k2t6wzhkhabz58ijbmguakywnhcjilsp3h7cubnl99lpl878x13xc633wn3mox has a CACAO that expired at 1674000468. Loading the stream with 'sync: SyncOptions.ALWAYS_SYNC' will restore the stream to a usable state, by discarding the invalid commits (this means losing the data from those invalid writes!)

I am running a local node, so from what I have seen here because I didn’t have a node running contantly, I think I need to re-deploy my composite? Not sure if I understood this all correctly. It seems like its pulling the data properly on the initial read.

Otherwise, where do I place {sync: SyncOptions.ALWAYS_SYNC} in this example to re-sync?


Hey Kevin, the blog post link is at Use 'Create Ceramic App' to Launch Your Project

Tagging in Elizabeth @anon16214351 for your questions

1 Like

Those CACAO errors happen when your streams aren’t getting successfully anchored. What Ceramic network is your node running on? Assuming you’re using the default, it would be running on the testnet-clay network (you should also see a log message at startup saying what network your node is connected to). If you create or update streams, you need to make sure your node stays online until those streams are successfully anchored by the anchor service. Otherwise when the anchor service tries to run it might fail to load the streams from your node, preventing them from getting anchored, and resulting in the CACAO expiration errors you see here.

The SyncOptions.ALWAYS_SYNC option is a part of the LoadOpts parameter to the loadStream method: CeramicClient | Ceramic Typescript Implementation

1 Like

thanks @spencer - I was running local and didn’t run a node for a few days so this makes sense.

In the example app given, there is no “loadStream”, only using composeDB/graphQL with a Ceramic DID in the previously mentioned example. Not sure if its possible for me to pass this through the graph queries, I will look for it.

I guess I searched since my last post, in the documents I’m not quite how to solve this. I get the fact that with GraphQL it appears the streamID is abstracted, but I also tried to find in the documentation, how to get streamID. I know I have read a few times its possible to get streamIDs owned by a DID, I apologize if I missed it but I can’t seem to find this.

hmm yeah it seems the LoadOpts aren’t exposed via the GraphQL APIs unfortunately. I’m not sure the best way to proceed TBH. The simplest solution would be to clear your node’s database and state store and start from scratch, if this is test-only data then that would work. If you need to try to preserve the data, you could look through your ceramic node logs for CACAO errors when loading the stream, the errors should include the streamids, which you could then load with SyncOptions.SYNC_ON_ERROR (this option was added to newer versions of Ceramic since my previous post - it behaves like SYNC_AWAYS in terms of restoring the stream to a usable state, but only does the work to resync the stream if there is actually an error, making it a bit safer to use).

@paul - How hard would it be to expose the LoadOpts to queries through the GraphQL APIs? Seems like that’s something we’ll want to add support for. CC @avi

Also sorry for the delayed reply @walletchat - the whole team has been very busy preparing the ComposeDB Beta that is launching this week


We are ok with whatever the solution is, mainly I just moved on because it was test data. But if the team suggests changing LoadOpts parameters and they are not exposed, it will just further confuse anyone that runs into this in the future. Realize you guys were overloaded, no worries. We figured it was better to revisit this after the madness was over :slight_smile:

1 Like

Appreciate your patience and understanding here! We’re really excited to be getting ComposeDB Beta out the door this week!

1 Like

ComposeDB uses the index query and multiquery APIs which AFAIK don’t support the LoadOpts options?

true, but they could be easily added to the server APIs. So I was wondering if we did that would it be easy to wire in and expose in the graphql apis?

We could have these options set on the ComposeClient instance and applied for all queries, but more granularity would be more tricky. Ideally these options shouldn’t be a runtime concern when running queries.

that’s very much not how they’ve been thought of at the Ceramic layer so far. CreateOpts, UpdateOpts, and LoadOpts are all designed to be passed on every relevant CRUD operation. So seems like there’s a disconnect here between how the Ceramic APIs are designed to be used and what’s possible with GraphQL. This is something we’re going to have to wrestle with.

@jthor @avi @msena