{"record":{"id":"a2d615fa53e78dc3","repo":"NanmiCoder/MediaCrawler","slug":"douyinstorefactory-create-store-invalid-save-opt","errorCode":null,"errorMessage":"[DouyinStoreFactory.create_store] Invalid save option only supported csv or db or json or sqlite or mongodb or excel ...","messagePattern":"\\[DouyinStoreFactory\\.create_store\\] Invalid save option only supported csv or db or json or sqlite or mongodb or excel \\.\\.\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"store/douyin/__init__.py","lineNumber":50,"sourceCode":"\n\nclass DouyinStoreFactory:\n    STORES = {\n        \"csv\": DouyinCsvStoreImplement,\n        \"db\": DouyinDbStoreImplement,\n        \"postgres\": DouyinDbStoreImplement,\n        \"json\": DouyinJsonStoreImplement,\n        \"jsonl\": DouyinJsonlStoreImplement,\n        \"sqlite\": DouyinSqliteStoreImplement,\n        \"mongodb\": DouyinMongoStoreImplement,\n        \"excel\": DouyinExcelStoreImplement,\n    }\n\n    @staticmethod\n    def create_store() -> AbstractStore:\n        store_class = DouyinStoreFactory.STORES.get(config.SAVE_DATA_OPTION)\n        if not store_class:\n            raise ValueError(\"[DouyinStoreFactory.create_store] Invalid save option only supported csv or db or json or sqlite or mongodb or excel ...\")\n        return store_class()\n\n\ndef _extract_note_image_list(aweme_detail: Dict) -> List[str]:\n    \"\"\"\n    Extract note image list\n\n    Args:\n        aweme_detail (Dict): Douyin content details\n\n    Returns:\n        List[str]: Note image list\n    \"\"\"\n    images_res: List[str] = []\n    images: List[Dict] = aweme_detail.get(\"images\", [])\n\n    if not images:\n        return []","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/NanmiCoder/MediaCrawler/blob/d6f7c5bb906b6dac40ddf343ef9e26438a3de092/store/douyin/__init__.py#L32-L68","documentation":"Raised by DouyinStoreFactory.create_store() when config.SAVE_DATA_OPTION is not a key of the douyin STORES registry (csv, db, postgres, json, jsonl, sqlite, mongodb, excel). Fail-fast guard at store creation time — the douyin crawler refuses to run with an unregistered persistence backend.","triggerScenarios":"SAVE_DATA_OPTION set to 'mysql' (the MySQL impl is registered under 'db'), 'xlsx' instead of 'excel', or any value not in the registry; triggered on first store access during a douyin crawl.","commonSituations":"Users migrating configs from other crawlers that use different option names; switching storage mid-project and misspelling the option; env var SAVE_DATA_OPTION overriding the intended base_config value.","solutions":["Use one of: csv, db, postgres, json, jsonl, sqlite, mongodb, excel — exactly lowercase","Prefer 'sqlite' for a zero-dependency local run; 'db' only if MySQL connection env vars are set","Verify the effective value: python -c 'import config; print(config.SAVE_DATA_OPTION)'","Register a custom store class in DouyinStoreFactory.STORES if you need an extra backend"],"exampleFix":"// before\nSAVE_DATA_OPTION = \"xlsx\"\n\n// after\nSAVE_DATA_OPTION = \"excel\"","handlingStrategy":"validation","validationCode":"from store.douyin import DouyinStoreFactory\n\nif config.SAVE_DATA_OPTION not in DouyinStoreFactory.STORES:\n    raise SystemExit(\n        f\"SAVE_DATA_OPTION={config.SAVE_DATA_OPTION!r} invalid; \"\n        f\"choose from {sorted(DouyinStoreFactory.STORES)}\"\n    )","typeGuard":"def is_valid_save_option(opt: str) -> bool:\n    return isinstance(opt, str) and opt in DouyinStoreFactory.STORES","tryCatchPattern":"try:\n    store = DouyinStoreFactory.create_store()\nexcept ValueError as e:\n    raise SystemExit(f\"fix config before crawling: {e}\") from e","preventionTips":["SAVE_DATA_OPTION is shared across platforms — set it once, correctly","'db' means MySQL; there is no 'mysql' key","Print repr() of the option to catch whitespace/case issues"],"tags":["configuration","storage","douyin","startup"],"backgroundTag":null,"analyzedSha":"d6f7c5bb906b6dac40ddf343ef9e26438a3de092","analyzedAt":"2026-08-15T01:39:07.505Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}