{"record":{"id":"6963a630f6c149ca","repo":"open-webui/open-webui","slug":"str-e-6963a6","errorCode":null,"errorMessage":"str(e)","messagePattern":"str\\(e\\)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"backend/open_webui/routers/models.py","lineNumber":475,"sourceCode":"                            user.id,\n                            user.role,\n                            new_model.access_grants,\n                            'sharing.public_models',\n                        )\n                        await Models.insert_new_model(user_id=user.id, form_data=new_model, db=db)\n            await publish_event(\n                request,\n                EVENTS.MODEL_IMPORTED,\n                actor=user,\n                subject_type='model',\n                data={'count': len(imported_ids), 'model_ids': imported_ids},\n            )\n            return True\n        else:\n            raise HTTPException(status_code=400, detail='Invalid JSON format')\n    except Exception as e:\n        log.exception(e)\n        raise HTTPException(status_code=500, detail=str(e))\n\n\n############################\n# SyncModels\n############################\n\n\nclass SyncModelsForm(BaseModel):\n    models: list[ModelModel] = []\n\n\n@router.post('/sync', response_model=list[ModelModel])\nasync def sync_models(\n    request: Request,\n    form_data: SyncModelsForm,\n    user=Depends(get_admin_user),\n    db: AsyncSession = Depends(get_async_session),\n):","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/open-webui/open-webui/blob/01f4282f1ffe0d6212f58d3afbeae21fffd0c4be/backend/open_webui/routers/models.py#L457-L493","documentation":"Generic 500 raised by the catch-all handler at the end of POST /api/v1/models/import (backend/open_webui/routers/models.py:475). Any non-HTTPException error escaping the import loop — most commonly a pydantic ValidationError when a malformed entry is coerced with ModelForm(**model_data), or a database failure during insert/update — is logged via log.exception and re-raised as HTTP 500 with the raw exception string as detail. Note the inner try/except only guards knowledge-file access; every other failure in the loop bubbles up.","triggerScenarios":"POST /api/v1/models/import where form_data.models is a list but an entry contains fields that fail ModelForm validation (wrong types in meta/params, bad access_grants shape, missing name), or the DB connection/commit fails mid-import. Entries with valid shape but invalid ids are silently skipped (is_valid_model_id), so this 500 specifically means schema/DB failure, not bad ids.","commonSituations":"Importing a models-export.json produced by a different (older/newer) Open WebUI version whose ModelForm schema has drifted; hand-edited export files; importing a file that contains tool/prompt exports mixed in; concurrent imports hitting a uniqueness conflict on model id; DB restart during import.","solutions":["Check the server log — log.exception(e) prints the full traceback with the offending entry; the 500 detail (str(e)) usually names the failing pydantic field.","Re-export the models from a source instance running the same Open WebUI version and import that file unmodified.","Validate each entry against the current ModelForm schema (id, name, meta, params types) before POSTing; drop or fix entries that fail.","If the traceback shows an IntegrityError/DB error, retry once the database is healthy; the endpoint is not transactional, so previously inserted models may need manual cleanup before re-import."],"exampleFix":"// before: importing a hand-edited payload with a bad params type\nawait fetch('/api/v1/models/import', {method:'POST', body: JSON.stringify({models: rawExport.models})}); // 500 'params Input should be a valid dictionary'\n\n// after: schema-check each entry client-side first\nconst valid = rawExport.models.filter(m =>\n  typeof m.id === 'string' && m.id &&\n  typeof m.name === 'string' &&\n  (m.params ?? {}) instanceof Object && !Array.isArray(m.params ?? {})\n);\nawait fetch('/api/v1/models/import', {method:'POST', body: JSON.stringify({models: valid})});","handlingStrategy":"validation","validationCode":"// Client-side: screen every entry before POST /api/v1/models/import\nfunction isValidModelEntry(m) {\n  return m && typeof m === 'object' &&\n    typeof m.id === 'string' && m.id.length > 0 &&\n    typeof m.name === 'string' && m.name.length > 0 &&\n    (m.meta === undefined || (m.meta instanceof Object && !Array.isArray(m.meta))) &&\n    (m.params === undefined || (m.params instanceof Object && !Array.isArray(m.params)));\n}\nconst payload = { models: exportData.models.filter(isValidModelEntry) };","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch('/api/v1/models/import', {method: 'POST', headers: authHeaders(), body: JSON.stringify(payload)});\n  if (!res.ok) {\n    const { detail } = await res.json();\n    // detail is the raw str(e): parse the pydantic field name out of it\n    console.error('import failed:', detail);\n    return { ok: false, reason: detail };\n  }\n  return { ok: true };\n} catch (networkErr) {\n  // transport-level failure only; HTTP errors handled above\n  throw networkErr;\n}","preventionTips":["Always import files exported by the same Open WebUI version you are importing into.","Never hand-edit exported JSON beyond simple field values; schema drift surfaces as an opaque 500.","Remember the endpoint is not atomic — a failure mid-list may leave earlier entries inserted; verify state after any 500.","Check server logs first: the traceback names the exact entry and field that failed."],"tags":["open-webui","models","import","validation","http-500"],"backgroundTag":null,"analyzedSha":"01f4282f1ffe0d6212f58d3afbeae21fffd0c4be","analyzedAt":"2026-08-14T18:25:22.715Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}