JuliusBrussee/caveman · error · Error

caveman build: config must use strict lock and required sand

Error message

caveman build: config must use strict lock and required sandbox

What it means

Thrown by `loadBuildInputs` for every CLI command that loads build config. It imports `caveman.config.ts` (or the passed path), reads the `default` or named `config` export, and hard-requires `config.lock === "strict"` and `config.sandbox === "required"`. Anything else — wrong export shape, missing config, or lenient settings — fails the build immediately: the framework only produces locks for strict-lock, required-sandbox builds.

Source

Thrown at packages/agent/src/cli.ts:1005

  "package.json",
  "package-lock.json",
  "npm-shrinkwrap.json",
  "pnpm-lock.yaml",
  "yarn.lock",
] as const;

async function loadBuildInputs(
  root: string,
  configPath: string,
  beforeSourceHash?: (
    inputs: Omit<LoadedBuildInputs, "sourceSha256">,
  ) => Promise<void>,
): Promise<LoadedBuildInputs> {
  const configAbsolute = resolve(root, configPath);
  const imported = await importFresh(configAbsolute) as { default?: BuildConfig; config?: BuildConfig };
  const config = imported.default ?? imported.config;
  if (!config || config.lock !== "strict" || config.sandbox !== "required") {
    throw new Error("caveman build: config must use strict lock and required sandbox");
  }
  const entryAbsolute = resolve(root, config.entry);
  const agent = await loadAgent(entryAbsolute);
  const evalFiles: string[] = [];
  for await (const path of glob(config.evals, { cwd: root })) evalFiles.push(resolve(root, path));
  evalFiles.sort();
  const evals: EvalDefinition[] = [];
  for (const path of evalFiles) {
    const module = await importFresh(path) as Record<string, unknown>;
    for (const value of Object.values(module)) {
      if (isEval(value)) evals.push(value);
    }
  }
  await beforeSourceHash?.({ config, agent, evals });
  const sourceFiles = new Set<string>([configAbsolute, entryAbsolute, ...evalFiles]);
  for (const pattern of SOURCE_PATTERNS) {
    for await (const path of glob(pattern, { cwd: root })) sourceFiles.add(resolve(root, path));
  }

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Set both literals in the config export: `lock: "strict"`, `sandbox: "required"`.
  2. Confirm the export is `export default` or `export const config`.
  3. If you intentionally need host sandbox (coding agents), use the code.ts session surface instead of the locked build CLI — `compile` refuses host mode anywhere in the graph.
  4. Check you passed the right config path as args[0]; the default is `caveman.config.ts` at the project root.

Example fix

// before
default export defineConfig({ lock: "strict", sandbox: "host" });

// after
export default defineConfig({ lock: "strict", sandbox: "required" });
Defensive patterns

Strategy: validation

Validate before calling

type BuildConfigShape = { lock?: unknown; sandbox?: unknown };

function configIsValid(config: BuildConfigShape | undefined): boolean {
  return !!config && config.lock === "strict" && config.sandbox === "required";
}
// assert configIsValid((await import(configPath)).default) before invoking the CLI

Type guard

function isStrictBuildConfig(v: unknown): v is { lock: "strict"; sandbox: "required" } {
  return typeof v === "object" && v !== null &&
    (v as { lock?: unknown }).lock === "strict" &&
    (v as { sandbox?: unknown }).sandbox === "required";
}

Try / catch

try {
  await build(args);
} catch (error) {
  if (error instanceof Error && error.message.includes("strict lock and required sandbox")) {
    // fix caveman.config.ts export and retry
  } else throw error;
}

Prevention

When it happens

Trigger: A `caveman.config.ts` exporting `{ lock: "loose" }` or `{ sandbox: "host" }` or omitting either field; exporting the config under a name that is neither `default` nor `config`; pointing `--config` at a file whose export is a plain object without the two required literal values.

Common situations: Copy-pasting a config template from an older version that defaulted these fields; switching sandbox to `host` for a coding agent and then trying the locked build path (host mode is lock-ineligible by design); typo in the export name (`export const buildConfig = ...` is not read).

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/52afed0fe8d9aa61. Report an issue: GitHub.