cayleygraph/cayley · error

ErrQuadStoreNotPersistent

ErrQuadStoreNotPersistent

Error message

cannot specify address for non-persistent backend

What it means

ErrQuadStoreNotPersistent is returned when a network address (KeyAddress) is supplied to a backend whose registration has IsPersistent == false. Non-persistent backends (e.g. memstore) cannot listen on an address. The CLI converts this into "...did you mean -i flag?".

Source

Thrown at graph/registry.go:24

//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package graph

import (
	"fmt"
	"sort"
)

var (
	ErrQuadStoreNotRegistred  = fmt.Errorf("this QuadStore is not registered")
	ErrQuadStoreNotPersistent = fmt.Errorf("cannot specify address for non-persistent backend")
	ErrOperationNotSupported  = fmt.Errorf("this Operation is not supported")
)

var storeRegistry = make(map[string]QuadStoreRegistration)

type NewStoreFunc func(string, Options) (QuadStore, error)
type InitStoreFunc func(string, Options) error
type UpgradeStoreFunc func(string, Options) error

type QuadStoreRegistration struct {
	NewFunc      NewStoreFunc
	UpgradeFunc  UpgradeStoreFunc
	InitFunc     InitStoreFunc
	IsPersistent bool
}

func RegisterQuadStore(name string, register QuadStoreRegistration) {
	if register.NewFunc == nil {

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Remove the address setting (viper.Set(KeyAddress, "")) when using a non-persistent backend
  2. Switch to a persistent backend (bolt, leveldb) if you need an address/HTTP serving of stored data
  3. Use the -i/--init flag flow the CLI suggests when loading data into a non-persistent store
  4. Check store registration flags before configuring an address

Example fix

// before
viper.Set("address", ":64210")
viper.Set("storage", "memstore") // not persistent -> error
// after
viper.Set("storage", "bolt") // persistent backend, or clear the address
viper.Set("address", ":64210")
Defensive patterns

Strategy: try-catch

Validate before calling

r, err := graph.NewQuadStore(name, "", nil) // or check registration flags via docs
persistent := name == "bolt" || name == "leveldb" // per registration metadata
if addr != "" && !persistent { clear addr before opening }

Type guard

func backendSupportsAddress(name string) bool {
    switch name { case "memstore": return false; default: return true }
}

Try / catch

h, err := openDatabase()
if errors.Is(err, graph.ErrQuadStoreNotPersistent) {
    viper.Set(KeyAddress, "")
    h, err = openDatabase() // retry without address
}

Prevention

When it happens

Trigger: Running cayley with an --address/-a against a non-persistent storage backend, or calling NewQuadStore/openForQueries with a non-empty dbpath for such a backend.

Common situations: Config leftover from a previous persistent backend (bolt/leveldb) while switching to memstore; assuming memstore supports serving on a port; copy-pasted startup scripts.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06). Data as JSON: /api/errors/93064bd31cf31466. Report an issue: GitHub.