paperclipai/paperclip · error · Error
workspace_durable_seed_missing
workspace_durable_seed_missing
Error message
workspace_durable_seed_missing
What it means
Guard in prepareSandboxManagedRuntime: the spec references a durable workspace seed archive, but the expected seed file is not present at runtime root before the workspace tarballs are built/extracted. The durable seed that should seed the workspace is missing entirely (as opposed to corrupted, which raises workspace_durable_seed_digest_mismatch).
Solutions
- Regenerate the durable seed archive for the workspace and re-run the prepare
- Fix the seed path in the runtime spec if it points at the wrong location
- Fall back to a full workspace sync (non-seeded) if the seed is optional for the run
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at packages/adapter-utils/src/sandbox-managed-runtime.ts:1096 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-10).
Data as JSON: /api/errors/e4a1d902a45a4ca9.
Report an issue: GitHub.
Appendix: source
Thrown at packages/adapter-utils/src/sandbox-managed-runtime.ts:1110
// access failure still fails the preparation: a workspace that exists but
// cannot be read must not silently become an empty remote workspace.
const syncWorkspace = input.syncWorkspace !== false &&
(await fs.access(input.workspaceLocalDir).then(
() => true,
(error: NodeJS.ErrnoException) => {
if (error.code === "ENOENT") return false;
throw error;
},
));
const workspaceInboundMode = input.workspaceInboundMode ?? "host_current";
const stageWorkspace =
syncWorkspace && workspaceInboundMode !== "adopt_remote";
const prepareWorkspaceSeed =
syncWorkspace &&
workspaceInboundMode === "adopt_remote" &&
input.workspaceDurableSeed !== undefined;
if (workspaceInboundMode === "durable_seed" && !input.workspaceDurableSeed) {
throw new Error("workspace_durable_seed_missing");
}
// Reject any unsafe asset key before an archive path or an asset directory is
// built from it. This runs before the git snapshot work so a bad key fails fast.
for (const asset of input.assets ?? []) {
assertRuntimeAssetKeyIsSafe(asset.key);
}
// Wrap a host-side staging sub-step or one scheduler task in its own span when
// the caller injects a runtime span runner. The runner defaults to a no-op, so
// a caller with no injected runner keeps the current control flow, and a
// throwing runner never changes it (see `createRuntimeSpanRunner`). The two
// pre-`pack` operations — the git enumeration and the baseline content-hash
// walk — parent under the `stage.sync` step, so they stop showing up as a
// hidden gap at the head of the step. Each inbound task (`stage.workspace`,
// `stage.asset.<key>`, `stage.project.<id>`) and each outbound restore task
// (`restore.workspace`, `restore.asset.<key>`) opens its own span, so two
// concurrent tasks produce overlapping spans and the `pack` span nests underView on GitHub (pinned to 3f1d897a7c)