NanmiCoder/MediaCrawler · error · ValueError

[TieBaStoreFactory.create_store] Invalid save option only su

Error message

[TieBaStoreFactory.create_store] Invalid save option only supported csv or db or json or sqlite or mongodb or excel ...

What it means

Raised by TieBaStoreFactory.create_store() when config.SAVE_DATA_OPTION is not a key in the tieba STORES registry (csv, db, postgres, json, jsonl, sqlite, mongodb, excel). Fail-fast so an unknown backend is rejected before any tieba note data is written.

Source

Thrown at store/tieba/__init__.py:46


class TieBaStoreFactory:
    STORES = {
        "csv": TieBaCsvStoreImplement,
        "db": TieBaDbStoreImplement,
        "postgres": TieBaDbStoreImplement,
        "json": TieBaJsonStoreImplement,
        "jsonl": TieBaJsonlStoreImplement,
        "sqlite": TieBaSqliteStoreImplement,
        "mongodb": TieBaMongoStoreImplement,
        "excel": TieBaExcelStoreImplement,
    }

    @staticmethod
    def create_store() -> AbstractStore:
        store_class = TieBaStoreFactory.STORES.get(config.SAVE_DATA_OPTION)
        if not store_class:
            raise ValueError(
                "[TieBaStoreFactory.create_store] Invalid save option only supported csv or db or json or sqlite or mongodb or excel ...")
        return store_class()


async def batch_update_tieba_notes(note_list: List[TiebaNote]):
    """
    Batch update tieba notes
    Args:
        note_list:

    Returns:

    """
    if not note_list:
        return
    for note_item in note_list:
        await update_tieba_note(note_item)

View on GitHub (pinned to d6f7c5bb90)

Solutions

  1. Use exactly one of: csv, db, postgres, json, jsonl, sqlite, mongodb, excel
  2. Print the effective value at startup to catch env-var overrides: python -c 'import config; print(repr(config.SAVE_DATA_OPTION))'
  3. Pick 'sqlite' or 'json' for dependency-free local crawling
  4. Add the missing backend to TieBaStoreFactory.STORES only if you implement an AbstractStore subclass for it

Example fix

// before
SAVE_DATA_OPTION = "json "

// after
SAVE_DATA_OPTION = "json"
Defensive patterns

Strategy: validation

Validate before calling

from store.tieba import TieBaStoreFactory

if config.SAVE_DATA_OPTION not in TieBaStoreFactory.STORES:
    raise SystemExit(
        f"SAVE_DATA_OPTION={config.SAVE_DATA_OPTION!r} invalid; "
        f"choose from {sorted(TieBaStoreFactory.STORES)}"
    )

Type guard

def is_valid_save_option(opt: str) -> bool:
    return isinstance(opt, str) and opt in TieBaStoreFactory.STORES

Try / catch

try:
    store = TieBaStoreFactory.create_store()
except ValueError as e:
    raise SystemExit(f"fix config before crawling: {e}") from e

Prevention

When it happens

Trigger: SAVE_DATA_OPTION set to a non-registry string (typo, wrong case, 'mysql' instead of 'db') and a tieba crawler run starts; raised at the first create_store() call.

Common situations: Copying SAVE_DATA_OPTION from another tool's docs; stale config after upgrading to a version that renamed options; whitespace or quotes accidentally included in the value.

Related errors


AI-assisted analysis of NanmiCoder/MediaCrawler@d6f7c5bb90 (2026-08-15). Data as JSON: /api/errors/0d80486a636ce4e3. Report an issue: GitHub.