Summary
crabbox run --id <lease-or-slug> can fail before resolving a healthy reusable lease when the
configured default provider differs from the provider recorded in the lease's local claim. The run
loads the configured provider first, so a missing credential for that unrelated provider prevents
reuse even though the exact claim already identifies the correct provider and the lease is ready.
This is a non-security lifecycle-routing bug. It was reproduced with a local-container lease while
the configured default was Hetzner with no Hetzner credential.
Steps to reproduce
-
In a Git repository, configure or inherit provider=hetzner without setting HCLOUD_TOKEN or
HETZNER_TOKEN.
-
Create a reusable local-container lease:
crabbox warmup \
--provider local-container \
--slug provider-resolution-repro \
--os ubuntu:24.04
-
Confirm the claim and lease are healthy:
crabbox inspect \
--provider local-container \
--id provider-resolution-repro \
--json
The reproduced lease reported provider=local-container and state=leased with a ready SSH
endpoint.
-
From the same repository, use the documented run-by-ID form without repeating the provider:
crabbox run --id provider-resolution-repro --no-sync -- true
echo "exit=$?"
-
Run the negative control against the same lease:
crabbox run \
--provider local-container \
--id provider-resolution-repro \
--no-sync \
-- true
-
Release the lease:
crabbox stop \
--provider local-container \
--target linux \
--id provider-resolution-repro
Expected behavior
When --id names an exact local claim for the current repository and the caller did not explicitly
select a provider, run should resolve the claim and use its recorded provider to reuse the lease.
An unrelated configured provider should not need to initialize successfully.
The red/green closure signal is:
- with
provider=hetzner configured and no Hetzner token, a claimed local-container lease succeeds
through crabbox run --id <slug> --no-sync -- true without an explicit provider; and
- an explicit
--provider remains authoritative, while a new run without --id retains the normal
configured-provider behavior.
Actual behavior
The run without --provider exits with status 3 before reaching the lease:
HCLOUD_TOKEN or HETZNER_TOKEN is required
exit=3
The negative control with --provider local-container reuses the same claim and lease successfully:
lease=cbx_98151bfa77b4 slug=provider-resolution-repro provider=local-container target=linux
running on 127.0.0.1 true
command complete
Affected area
internal/cli/run.go, particularly provider loading and reusable-lease resolution in
runCommandWithBenchmarkRecord.
- Local lease claims used by
run --id to bind a lease to its repository and provider.
- The provider-agnostic
run --id examples and reuse contract in docs/commands/run.md.
Runtime or environment
- Crabbox CLI:
0.40.0
- Current source also inspected at
main revision
ce9487f552054326d9209d3ba9606d01a36f5666
- Host: macOS ARM64
- Container runtime: Docker client/server
29.6.2, Linux ARM64 server
- Lease provider:
local-container
- Configured default provider:
hetzner
- Coordinator: not configured
Evidence
The current main implementation loads configuration, applies lease flags, and calls
loadBackend(cfg, ...) before reusable-lease resolution. When --provider is absent, the configured
Hetzner provider therefore initializes first and rejects the missing credential before the supplied
slug can resolve to its local-container claim.
The claim itself was valid: explicit-provider inspect returned a ready local-container lease, and
the explicit-provider control ran true on it successfully. The only changed input between the red
and green runs was --provider local-container.
docs/commands/run.md describes --id as reusing an existing lease and repeatedly demonstrates
crabbox run --id <slug> ... without a provider flag. The concepts documentation also says the local
claim is required for run --id to resolve slugs and enforce repository ownership.
Open and closed Crabbox issues and pull requests were searched on 2026-08-08 for run --id, provider
resolution, lease claims, configured defaults, and the Hetzner credential error. No report for this
exact run-by-ID failure was found.
Impact
Reusable lease handles are not self-sufficient when the user's configured provider changes or when a
lease was created with a one-command provider override. Documented run --id workflows can fail with
an opaque credential error for a provider unrelated to the target lease, forcing callers to remember
and repeat provider-specific routing state already present in the claim.
This affects automation and handoffs in particular: a stable lease ID or slug appears sufficient, but
the command can stop before inspecting it.
Additional context
This is distinct from these existing open issues:
The current workaround is to repeat the provider on every reused command:
crabbox run --provider local-container --id <lease-or-slug> -- <command>
Summary
crabbox run --id <lease-or-slug>can fail before resolving a healthy reusable lease when theconfigured default provider differs from the provider recorded in the lease's local claim. The run
loads the configured provider first, so a missing credential for that unrelated provider prevents
reuse even though the exact claim already identifies the correct provider and the lease is ready.
This is a non-security lifecycle-routing bug. It was reproduced with a
local-containerlease whilethe configured default was Hetzner with no Hetzner credential.
Steps to reproduce
In a Git repository, configure or inherit
provider=hetznerwithout settingHCLOUD_TOKENorHETZNER_TOKEN.Create a reusable local-container lease:
Confirm the claim and lease are healthy:
The reproduced lease reported
provider=local-containerandstate=leasedwith a ready SSHendpoint.
From the same repository, use the documented run-by-ID form without repeating the provider:
Run the negative control against the same lease:
crabbox run \ --provider local-container \ --id provider-resolution-repro \ --no-sync \ -- trueRelease the lease:
Expected behavior
When
--idnames an exact local claim for the current repository and the caller did not explicitlyselect a provider,
runshould resolve the claim and use its recorded provider to reuse the lease.An unrelated configured provider should not need to initialize successfully.
The red/green closure signal is:
provider=hetznerconfigured and no Hetzner token, a claimedlocal-containerlease succeedsthrough
crabbox run --id <slug> --no-sync -- truewithout an explicit provider; and--providerremains authoritative, while a new run without--idretains the normalconfigured-provider behavior.
Actual behavior
The run without
--providerexits with status 3 before reaching the lease:The negative control with
--provider local-containerreuses the same claim and lease successfully:Affected area
internal/cli/run.go, particularly provider loading and reusable-lease resolution inrunCommandWithBenchmarkRecord.run --idto bind a lease to its repository and provider.run --idexamples and reuse contract indocs/commands/run.md.Runtime or environment
0.40.0mainrevisionce9487f552054326d9209d3ba9606d01a36f566629.6.2, Linux ARM64 serverlocal-containerhetznerEvidence
The current
mainimplementation loads configuration, applies lease flags, and callsloadBackend(cfg, ...)before reusable-lease resolution. When--provideris absent, the configuredHetzner provider therefore initializes first and rejects the missing credential before the supplied
slug can resolve to its
local-containerclaim.The claim itself was valid: explicit-provider
inspectreturned a readylocal-containerlease, andthe explicit-provider control ran
trueon it successfully. The only changed input between the redand green runs was
--provider local-container.docs/commands/run.mddescribes--idas reusing an existing lease and repeatedly demonstratescrabbox run --id <slug> ...without a provider flag. The concepts documentation also says the localclaim is required for
run --idto resolve slugs and enforce repository ownership.Open and closed Crabbox issues and pull requests were searched on 2026-08-08 for
run --id, providerresolution, lease claims, configured defaults, and the Hetzner credential error. No report for this
exact run-by-ID failure was found.
Impact
Reusable lease handles are not self-sufficient when the user's configured provider changes or when a
lease was created with a one-command provider override. Documented
run --idworkflows can fail withan opaque credential error for a provider unrelated to the target lease, forcing callers to remember
and repeat provider-specific routing state already present in the claim.
This affects automation and handoffs in particular: a stable lease ID or slug appears sufficient, but
the command can stop before inspecting it.
Additional context
This is distinct from these existing open issues:
doctortreating the unchosencompiled Hetzner default as a hard readiness failure. This report concerns an explicit reusable
lease whose claim identifies another provider.
inventory while intentionally preserving provider-scoped
list. This report concerns executionrouting for one exact claimed lease.
local-container; it does not cover provider selection for lease reuse.The current workaround is to repeat the provider on every reused command: