JuliusBrussee/caveman · error

native runtime: store is required

Error message

native runtime: store is required

What it means

ServeUnix requires a Runtime carrying a non-nil ccr store before it will create the Unix socket. Because each socket call can only serve decisions from the store, a store-less runtime is a configuration error detected up front.

Solutions

  1. Construct the Runtime via its constructor with an opened *ccr.Store before calling ServeUnix.
  2. Check the store-open error at startup and abort serving instead of continuing with a nil store.
  3. Guard the caller: if runtime == nil || runtime.store == nil, skip serving the native runtime and log.
  4. Serve() (the public entry) may wrap ServeUnix — ensure the store is attached before invoking it too.

Example fix

// before
rt := &nativeruntime.Runtime{}
go nativeruntime.ServeUnix(ctx, sockPath, rt)
// after
rt, err := nativeruntime.NewRuntime(store)
if err != nil { return err }
go nativeruntime.ServeUnix(ctx, sockPath, rt)
Defensive patterns

Strategy: validation

Validate before calling

if rt == nil || rt.Store == nil {
    return errors.New("native runtime requires an initialized store")
}

Type guard

func servable(rt *nativeruntime.Runtime) bool { return rt != nil && rt.Store != nil }

Try / catch

if err := nativeruntime.ServeUnix(ctx, path, rt); err != nil {
    if strings.Contains(err.Error(), "store is required") {
        log.Error("native runtime disabled: ccr store not initialized")
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: ServeUnix(ctx, path, runtime) called with runtime == nil or runtime == &Runtime{} without a store set (e.g. constructing Runtime manually in tests or wiring the server before store initialization succeeded).

Common situations: Store failed to open earlier but startup continued; hand-assembling Runtime in tests/benchmarks; wiring order bug where Serve starts before NewRuntime returns a store-backed runtime.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/58fce7249d497adf. Report an issue: GitHub.

Appendix: source

Thrown at proxy/internal/nativeruntime/server_unix.go:34

// choose this path, preventing one integration from impersonating another
// user's runtime.
func SocketPath(home string) string { return filepath.Join(home, "run", "native.sock") }

func dialNativeRuntime(ctx context.Context, home string) (net.Conn, error) {
	return (&net.Dialer{}).DialContext(ctx, "unix", SocketPath(home))
}

// Serve binds runtime transport for current platform.
func Serve(ctx context.Context, home string, runtime *Runtime) error {
	return ServeUnix(ctx, SocketPath(home), runtime)
}

// ServeUnix exposes one-request-per-connection JSON over a user-only Unix
// socket. Runtime errors close or fail-open the individual call; they never stop
// the coding agent or the provider proxy.
func ServeUnix(ctx context.Context, path string, runtime *Runtime) error {
	if runtime == nil || runtime.store == nil {
		return errors.New("native runtime: store is required")
	}
	if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
		return fmt.Errorf("native runtime mkdir: %w", err)
	}
	if err := os.Chmod(filepath.Dir(path), 0o700); err != nil {
		return fmt.Errorf("native runtime chmod dir: %w", err)
	}
	if _, err := os.Stat(path); err == nil {
		conn, dialErr := net.DialTimeout("unix", path, 50*time.Millisecond)
		if dialErr == nil {
			_ = conn.Close()
			return errors.New("native runtime: socket already active")
		}
		if err := os.Remove(path); err != nil {
			return fmt.Errorf("native runtime remove stale socket: %w", err)
		}
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("native runtime inspect socket: %w", err)

View on GitHub (pinned to 3ee70a1026)