shareAI-lab/learn-claude-code · error · WorkflowInputError

meta.name must be a 1-64 character slug using letters, numbe

Error message

meta.name must be a 1-64 character slug using letters, numbers, '.', '_', or '-'

What it means

meta.name must fully match ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ : 1-64 characters, starting with a letter or digit, containing only letters, digits, '.', '_', '-'. The strictness exists because the name is embedded in the run id, filesystem paths (<runId>.json, .journal.jsonl, .lock), and the permission allow/deny lists — spaces or slashes would break all three.

Source

Thrown at s16_workflow_runtime/code.py:127

            try:
                fcntl.flock(handle.fileno(), fcntl.LOCK_UN)
            finally:
                handle.close()
        local_lock.release()
        with _run_locks_guard:
            if not local_lock.locked() and _run_locks.get(run_id) is local_lock:
                _run_locks.pop(run_id, None)


# -- Metadata Validation --
def validate_meta(meta):
    """Validate name, description, and optional phases before launch."""
    if not isinstance(meta, dict):
        raise WorkflowInputError("meta must be an object literal")
    if not meta.get("name") or not meta.get("description"):
        raise WorkflowInputError("meta requires `name` and `description`")
    if not isinstance(meta["name"], str) or not WORKFLOW_NAME_RE.fullmatch(meta["name"]):
        raise WorkflowInputError(
            "meta.name must be a 1-64 character slug using letters, numbers, '.', '_', or '-'"
        )
    if not isinstance(meta["description"], str):
        raise WorkflowInputError("meta.description must be a string")
    if "phases" in meta:
        if not isinstance(meta["phases"], list) or not all(
            isinstance(phase, str) and phase for phase in meta["phases"]
        ):
            raise WorkflowInputError("meta.phases must be a list of non-empty strings")
    return meta


def check_permission(meta, settings=None):
    """Apply the s03 allow/deny gate before launching a workflow."""
    settings = settings or {}
    if meta["name"] in settings.get("deny", []):
        raise WorkflowInputError(f"workflow '{meta['name']}' denied by settings")
    return "allow"

View on GitHub (pinned to 985456f4ad)

Solutions

  1. Slugify: lowercase, replace whitespace/punctuation with '-', strip leading separators
  2. Move version info into description or keep it after a '.'/'-' that is not the first character
  3. Apply the same regex client-side before submitting to run()

Example fix

# before
meta = {"name": "Data Pipeline (nightly)", "description": "..."}

# after
meta = {"name": "data-pipeline-nightly", "description": "..."}
Defensive patterns

Strategy: validation

Validate before calling

import re
NAME_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$")

def is_valid_workflow_name(name) -> bool:
    return isinstance(name, str) and bool(NAME_RE.fullmatch(name))

assert is_valid_workflow_name(meta["name"]), f"invalid workflow name: {meta['name']!r}"

Type guard

def is_slug_name(name) -> bool:
    import re
    return isinstance(name, str) and bool(re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]{0,63}", name))

Try / catch

try:
    validate_meta(meta)
except WorkflowInputError as exc:
    if "meta.name" in str(exc):
        import re as _re
        slug = _re.sub(r"[^A-Za-z0-9._-]+", "-", meta["name"]).strip("-.")[:64]
        meta = {**meta, "name": slug}
        validate_meta(meta)
    else:
        raise

Prevention

When it happens

Trigger: Names with spaces ('data pipeline'), leading separators ('-ingest'), colons or other punctuation ('ingest:v2'), unicode characters, or names longer than 64 characters. Names starting with '.' or '-' fail the first-character rule.

Common situations: Using human-readable titles as the machine name. Copying Docker image tags or version strings ('ingest:latest') into name. Auto-generating names from free text without slugification.

Related errors


AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14). Data as JSON: /api/errors/b1934fe2510b75d5. Report an issue: GitHub.