VectifyAI/PageIndex · error · ValueError

Invalid doc_id: {doc_id!r}

Error message

Invalid doc_id: {doc_id!r}

What it means

save_document() validates doc_id through _doc_dir(); when it returns None the identifier can't be mapped to a safe on-disk directory (empty, wrong type, or containing path-traversal/invalid characters). The ValueError aborts before any files are written or the manifest is touched.

Source

Thrown at pageindex/local_store.py:118

        pre-existing best-effort behavior stays."""
        try:
            import fcntl
        except ImportError:
            yield
            return
        self._root.mkdir(parents=True, exist_ok=True)
        with open(self._root / ".lock", "w") as handle:
            fcntl.flock(handle, fcntl.LOCK_EX)
            try:
                yield
            finally:
                fcntl.flock(handle, fcntl.LOCK_UN)

    # ── documents ──
    def save_document(self, doc_id: str, meta: dict, tree: list, pages: list) -> None:
        doc_dir = self._doc_dir(doc_id)
        if doc_dir is None:
            raise ValueError(f"Invalid doc_id: {doc_id!r}")
        doc_dir.mkdir(parents=True, exist_ok=True)
        _write_json_atomic(doc_dir / "tree.json", tree)
        _write_json_atomic(doc_dir / "pages.json", pages)
        _write_json_atomic(doc_dir / "doc.json", meta)
        manifest = self._read_manifest()
        manifest[doc_id] = meta
        self._write_manifest(manifest)

    def _read_doc_file(self, doc_id: str, name: str):
        doc_dir = self._doc_dir(doc_id)
        if doc_dir is None or not (doc_dir / "doc.json").is_file():
            return None
        return _read_json(doc_dir / name)

    def get_meta(self, doc_id: str) -> dict | None:
        doc_dir = self._doc_dir(doc_id)
        if doc_dir is None or not (doc_dir / "doc.json").is_file():
            return None

View on GitHub (pinned to afb5e11976)

Solutions

  1. Use a clean identifier: non-empty string of safe characters (letters, digits, '-', '_') or a uuid4 hex
  2. Sanitize/validate doc_id before calling submit_document
  3. Check _doc_dir()'s accepted pattern and conform to it

Example fix

# before
client.submit_document(doc_id=user_filename, ...)  # e.g. '../etc/passwd'
# after
import uuid
client.submit_document(doc_id=uuid.uuid4().hex, ...)
Defensive patterns

Strategy: validation

Validate before calling

import re, uuid
SAFE = re.compile(r'^[A-Za-z0-9_-]{1,128}$')
doc_id = doc_id if SAFE.match(str(doc_id or '')) else uuid.uuid4().hex

Type guard

def is_safe_doc_id(v) -> bool:
    import re
    return isinstance(v, str) and bool(re.fullmatch(r'[A-Za-z0-9_-]{1,128}', v))

Try / catch

try:
    client.submit_document(doc_id, ...)
except ValueError as e:
    if 'Invalid doc_id' in str(e):
        doc_id = uuid.uuid4().hex
        client.submit_document(doc_id, ...)

Prevention

When it happens

Trigger: Calling submit_document()/save_document() with doc_id='' , doc_id=None, or values like '../../etc' or names with characters the store refuses — anything for which _doc_dir() yields None.

Common situations: Generating doc_ids from un-sanitized user input or filenames; passing an int id instead of str; empty string slipping through an upload form.

Related errors


AI-assisted analysis of VectifyAI/PageIndex@afb5e11976 (2026-08-27). Data as JSON: /api/errors/0fb2ea6c7a6c4bc6. Report an issue: GitHub.