mvanhorn/last30days-skill · error · ValueError

invalid library ID in {id_path}

Error message

invalid library ID in {id_path}

What it means

Raised by get_or_create_library_id in library.py when the persisted library ID file (memory_dir/<LIBRARY_ID_FILENAME>) exists but its content does not match _LIBRARY_ID = r'[0-9a-f]{32}' — a 32-char lowercase hex string (a uuid4().hex). The ID namespaces one research library; a corrupt or hand-edited value breaks brief-name generation downstream, so it fails fast with ValueError naming the offending path.

Source

Thrown at skills/last30days/scripts/lib/library.py:90

    return slug or "last30days"


def get_or_create_library_id(memory_dir: Path | str) -> str:
    """Return the persisted random namespace for one research library."""
    memory_path = Path(memory_dir).expanduser()
    memory_path.mkdir(parents=True, exist_ok=True)
    id_path = memory_path / LIBRARY_ID_FILENAME
    try:
        library_id = id_path.read_text(encoding="utf-8").strip()
    except FileNotFoundError:
        library_id = uuid.uuid4().hex
        try:
            with id_path.open("x", encoding="utf-8") as handle:
                handle.write(f"{library_id}\n")
        except FileExistsError:
            library_id = id_path.read_text(encoding="utf-8").strip()
    if not _LIBRARY_ID.fullmatch(library_id):
        raise ValueError(f"invalid library ID in {id_path}")
    return library_id


def is_generated_brief_name(name: str) -> bool:
    """Return whether a filename has the exact library-renderer output shape."""
    return _GENERATED_BRIEF_NAME.fullmatch(name) is not None


def scan_library(
    memory_dir: Path | str = DEFAULT_MEMORY_DIR,
    briefs_dir: Path | str = DEFAULT_BRIEFS_DIR,
) -> tuple[list[LibraryEntry], list[str]]:
    """Return valid saved entries and notes for files that could not be read.

    Hand-edited and foreign files are tolerated: a generic Markdown heading is
    enough to include a file, while unreadable or unrecognizable files are
    skipped with a note instead of aborting the entire feed generation.
    """

View on GitHub (pinned to c7460f6114)

Solutions

  1. Regenerate the ID: delete the ID file and re-run — get_or_create_library_id will create a fresh uuid4().hex via the exclusive-create path.
  2. Or restore the file content to a valid 32-lowercase-hex value if the original ID must be preserved (brief names embed it).
  3. Check what wrote the bad value (editor, sync tool, seeding script) so it does not recur.

Example fix

# before: id file contains
550E8400-E29B-41D4-A716-446655440000

# after: regenerate
rm ~/.config/last30days/memory/<library-id-file>
python -c "from last30days.scripts.lib.library import get_or_create_library_id; get_or_create_library_id('<memory_dir>')"
Defensive patterns

Strategy: validation

Validate before calling

import re
from pathlib import Path

LIBRARY_ID = re.compile(r"[0-9a-f]{32}")

def library_id_ok(memory_dir: Path) -> bool:
    id_file = memory_dir / LIBRARY_ID_FILENAME
    return LIBRARY_ID.fullmatch(id_file.read_text(encoding="utf-8").strip()) is not None

Type guard

import re

_LIBRARY_ID = re.compile(r"[0-9a-f]{32}")

def is_valid_library_id(value: object) -> bool:
    return isinstance(value, str) and _LIBRARY_ID.fullmatch(value) is not None

Try / catch

try:
    lib_id = get_or_create_library_id(memory_dir)
except ValueError as e:
    if 'invalid library ID' in str(e):
        (memory_dir / LIBRARY_ID_FILENAME).unlink(missing_ok=True)
        lib_id = get_or_create_library_id(memory_dir)  # regenerates a fresh uuid4().hex

Prevention

When it happens

Trigger: The ID file was hand-edited (uppercase UUID with dashes pasted in, e.g. '550E8400-E29B-...'), truncated by an interrupted write, filled with a placeholder like 'my-library', or corrupted by disk/sync tools; a non-UTF-8 file would surface earlier at read_text.

Common situations: Users open the file out of curiosity and 'fix' the ID; cloud-sync or backup tools mangle dot-files; scripts seed the memory dir with example content including a fake ID; partial writes from a crashed first run.

Related errors


AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15). Data as JSON: /api/errors/baf8aeb32486f626. Report an issue: GitHub.