mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 01:29:56 +00:00
fix(crabbox): staging recovery fails when any local claim is unattached (#159848)
Crabbox records provider resources that are not yet attached to a repository with an empty repoRoot (ClaimLeaseTargetForConfig with allowEmptyRepoRoot), and refuses to replace an attached root without --reclaim. The staging claims inventory required every repoRoot to be absolute, so one unattached claim anywhere in the local namespace made the whole inventory "unsupported or malformed" and held every staging entry, including the automatic end-of-run recovery. Accept the empty root and skip it during source matching; it names no staging source and must not be resolved against the process cwd.
This commit is contained in:
parent
687ab1d101
commit
69c798e965
2 changed files with 25 additions and 2 deletions
|
|
@ -30,7 +30,9 @@ const inventorySchema = z.object({
|
|||
.array(
|
||||
z.object({
|
||||
leaseId: z.string().min(1).max(512),
|
||||
repoRoot: pathSchema,
|
||||
// Crabbox records provider resources not yet attached to a repository
|
||||
// with an empty root, and never clears an attached root without reclaim.
|
||||
repoRoot: z.union([z.literal(""), pathSchema]),
|
||||
}),
|
||||
)
|
||||
.max(10_000),
|
||||
|
|
@ -304,7 +306,7 @@ export async function verifyNoStagingClaims(params: {
|
|||
if (Date.now() >= deadline) {
|
||||
throw new ClaimInventoryHold("Native claim inventory exceeded its inspection budget.");
|
||||
}
|
||||
if (within(sourceRoot, directoryLocation(claim.repoRoot).directory)) {
|
||||
if (claim.repoRoot && within(sourceRoot, directoryLocation(claim.repoRoot).directory)) {
|
||||
matches.add(claim.leaseId);
|
||||
if (matches.size === 16) {
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -172,6 +172,27 @@ it("returns only bounded matching lease IDs for source descendants and canonical
|
|||
}
|
||||
});
|
||||
|
||||
it("ignores native claims not attached to any repository", async () => {
|
||||
const context = fixture();
|
||||
nativeResponse(
|
||||
output([
|
||||
{ leaseId: "cbx_unattached", repoRoot: "" },
|
||||
{ leaseId: "cbx_neighbor", repoRoot: context.source + "-neighbor" },
|
||||
]),
|
||||
);
|
||||
expect(await verifyNoStagingClaims(context)).toEqual({ ok: true });
|
||||
nativeResponse(
|
||||
output([
|
||||
{ leaseId: "cbx_unattached", repoRoot: "" },
|
||||
{ leaseId: "cbx_stage", repoRoot: context.source },
|
||||
]),
|
||||
);
|
||||
expect(await verifyNoStagingClaims(context)).toMatchObject({
|
||||
ok: false,
|
||||
matchingLeaseIds: ["cbx_stage"],
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
["nonzero partial inventory", output(), 2],
|
||||
[
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue