ruvnet/ruflo · error · InMemoryFenceReferenceError
invalid-request
invalid-request
Error message
${label} must be non-empty What it means
The in-memory fenced-lease reference validates every identity string with a trim-and-non-empty check: repositoryId, sessionId, and workloadId (plus lease scopes via normalizeScope) on the acquire/renew paths. An empty or whitespace-only value throws InMemoryFenceReferenceError with reason 'invalid-request' and a message naming the failed field. This adapter is a single-process conformance reference; distributed adapters enforce the same request shape.
Source
Thrown at v3/@claude-flow/codex/src/harness/in-memory-fenced-lease-reference.ts:34
export class InMemoryFenceReferenceError extends Error {
constructor(readonly reason: InMemoryFenceRefusal, detail: string) {
super(detail);
}
}
interface StoredLease {
lease: FencedLease;
expiresAtMs: number;
}
function compare(left: string, right: string): number {
return left < right ? -1 : left > right ? 1 : 0;
}
function text(value: string, label: string): string {
const result = value.trim();
if (!result) throw new InMemoryFenceReferenceError('invalid-request', `${label} must be non-empty`);
return result;
}
function normalizeScope(kind: LeaseRequest['kind'], value: string): string {
const scope = text(value, 'lease scope');
if (scope.startsWith('-') || scope.includes('\\') || scope !== scope.normalize('NFC')) {
throw new InMemoryFenceReferenceError('invalid-request', `unsafe lease scope: ${value}`);
}
if (kind === 'resource') {
if (scope.includes('/') || scope === '.' || scope === '..') {
throw new InMemoryFenceReferenceError('invalid-request', `invalid named resource: ${value}`);
}
return scope;
}
if (
scope.startsWith('/')
|| scope.split('/').some((part) => !part || part === '.' || part === '..')
) {View on GitHub (pinned to fa13ee4ad6)
Solutions
- Check the field named in the message and supply a real value
- Derive ids from stable sources (git remote, a session uuid) instead of optional flags
- Apply the same trim-and-check guard when building requests so callers get your error message with context
Example fix
// before
ref.acquire({ repositoryId: '', kind: 'resource', scopes: ['db-main'], ttlMs: 30_000, sessionId: 's1', workloadId: 'w1' });
// after
ref.acquire({ repositoryId: 'github.com/org/repo', kind: 'resource', scopes: ['db-main'], ttlMs: 30_000, sessionId: 's1', workloadId: 'w1' }); Defensive patterns
Strategy: try-catch
Validate before calling
function isNonBlank(value: unknown): value is string {
return typeof value === 'string' && value.trim().length > 0;
} Type guard
function isNonBlank(value: unknown): value is string {
return typeof value === 'string' && value.trim().length > 0;
} Try / catch
try { lease = ref.acquire(request); } catch (error) { if (error instanceof InMemoryFenceReferenceError && error.reason === 'invalid-request') { // fix the field named in error.message, then retry with a corrected request } throw error; } Prevention
- Default identity fields from stable sources (repo remote, session uuid) instead of optional flags
- Guard requests with a non-blank check before calling the adapter
- Distinguish reason 'invalid-request' from 'scope-conflict'/'stale-fence' — only the first means your payload is malformed
When it happens
Trigger: Calling acquire with repositoryId: '' or a whitespace-only sessionId/workloadId; renew/release paths invoked with blank identity fields; requests assembled from optional variables that were never assigned and default to empty string.
Common situations: Session ids plumbed from optional CLI flags that default to ''; multi-repository loops where one repo's id is missing; user input trimmed to '' before being passed on.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- ${label} must be non-empty
- ${label} must be a canonical sha256 digest
- build evidence path is not a file or symlink: ${path}
- duplicate declared build input
- duplicate declared toolchain
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/1cc37fb0eb7ff2c5.
Report an issue: GitHub.