ruvnet/ruflo · error · Error

label may only contain [A-Za-z0-9_.\\-:/@]

Error message

label may only contain [A-Za-z0-9_.\\-:/@]

What it means

Thrown by validateLabel() (agenticow-loader.ts:91) when a branch/checkpoint label contains characters outside the whitelist regex ^[A-Za-z0-9_.\-:/@]+$. The whitelist keeps labels filesystem-safe and manifest-JSON-safe since they become keys and path components in the COW lineage manifest.

Solutions

  1. Replace spaces with '-' or '_' and strip punctuation: label.replace(/[^A-Za-z0-9_.\-:/@]/g, '-')
  2. Use slug/kebab-case labels ('exp-3-nn-branch')
  3. If you need arbitrary text, store it in the record's text field, not the label

Example fix

// before
await callTool('agenticow_checkpoint', { path: p, label: 'fix attempt #1 (auth)' });
// throws: label may only contain [A-Za-z0-9_.\-:/@]

// after
await callTool('agenticow_checkpoint', { path: p, label: 'fix-attempt-1-auth' });
Defensive patterns

Strategy: validation

Validate before calling

const LABEL_RE = /^[A-Za-z0-9_.\-:/@]+$/;
function sanitizeLabel(raw: string): string {
  return raw.replace(/[^A-Za-z0-9_.\-:/@]/g, '-').slice(0, 256);
}
const label = sanitizeLabel(userInput);
if (!LABEL_RE.test(label)) throw new TypeError('label charset invalid');

Try / catch

try {
  await callTool('agenticow_checkpoint', args);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('label may only contain')) {
    args.label = sanitizeLabel(args.label);
    return callTool('agenticow_checkpoint', args);
  }
  throw e;
}

Prevention

When it happens

Trigger: A label containing spaces ('fix attempt 1'), commas, parentheses, unicode, '#', '+', or any symbol outside A-Z a-z 0-9 _ . - : / @ — submitted to agenticow_branch, agenticow_checkpoint, agenticow_rollback, agenticow_promote, or as an agenticow_speculate candidate label.

Common situations: Human-typed labels with spaces or punctuation; labels localized to non-Latin scripts; templated labels that interpolate markdown or user free text.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/5508e0ded8c16288. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/cli/src/mcp-tools/agenticow-loader.ts:91

  return isAbsolute(path) ? path : resolve(getProjectCwd(), path);
}

/**
 * Lineage manifest companion path. agenticow persists the COW chain
 * (working → checkpoints → base) into `<file>.agenticow.json` next to the
 * `.rvf` data file. Without it, forks/checkpoints are in-memory only and
 * disappear when the AgenticMemory handle closes.
 */
export function manifestFor(file: string): string {
  return `${file}.agenticow.json`;
}

/** Validate a COW branch/checkpoint label (alnum + a small safe symbol set). */
export function validateLabel(label: string): string {
  if (!label || typeof label !== 'string') throw new Error('label is required');
  if (label.length > 256) throw new Error('label exceeds 256 chars');
  if (!/^[A-Za-z0-9_.\-:/@]+$/.test(label)) {
    throw new Error('label may only contain [A-Za-z0-9_.\\-:/@]');
  }
  return label;
}

/**
 * Open (or create) a memory file, restoring its COW chain from the lineage
 * manifest when one exists. When neither the `.rvf` nor the manifest exists,
 * `dimension` is required to create a fresh base.
 */
export async function openWithLineage(api: AgenticowApi, file: string, dimension?: number) {
  const manifest = manifestFor(file);
  if (existsSync(manifest)) {
    return (api.AgenticMemory as any).load(manifest);
  }
  const opts: any = {};
  if (typeof dimension === 'number' && Number.isInteger(dimension) && dimension > 0) {
    opts.dimension = dimension;
  } else if (!existsSync(file)) {

View on GitHub (pinned to fa13ee4ad6)