{"record":{"id":"24e2feba61b96879","repo":"TryGhost/Ghost","slug":"cannot-create-without-a-persistence-adapter-use-b","errorCode":null,"errorMessage":"Cannot create without a persistence adapter. Use buildMany() for in-memory objects.","messagePattern":"Cannot create without a persistence adapter\\. Use buildMany\\(\\) for in-memory objects\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"e2e/data-factory/factory.ts","lineNumber":28,"sourceCode":"    }\n\n    abstract build(options?: Partial<TOptions>): TResult;\n\n    buildMany(optionsList: Partial<TOptions>[]): TResult[] {\n        return optionsList.map(options => this.build(options));\n    }\n\n    async create(options?: Partial<TOptions>): Promise<TResult> {\n        if (!this.adapter) {\n            throw new Error('Cannot create without a persistence adapter. Use build() for in-memory objects.');\n        }\n        const data = this.build(options);\n        return await this.adapter.insert(this.entityType, data) as Promise<TResult>;\n    }\n\n    async createMany(optionsList: Partial<TOptions>[]): Promise<TResult[]> {\n        if (!this.adapter) {\n            throw new Error('Cannot create without a persistence adapter. Use buildMany() for in-memory objects.');\n        }\n\n        const results: TResult[] = [];\n        for (const options of optionsList) {\n            const result = await this.create(options);\n            results.push(result);\n        }\n        return results;\n    }\n}\n","sourceCodeStart":10,"sourceCodeEnd":39,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/e2e/data-factory/factory.ts#L10-L39","documentation":"Thrown by Factory.createMany() when the factory was constructed without a PersistenceAdapter. Factories support two modes: build()/buildMany() produce in-memory objects (no adapter needed), while create()/createMany() persist through an adapter. Calling createMany() without an adapter is a programming error — the factory cannot know where to insert. The error message points you to the correct in-memory alternative.","triggerScenarios":"Test code instantiates a factory via 'new MyFactory()' (no adapter) and then calls factory.createMany([...]) expecting persistence. The base Factory class guards both create() and createMany() with this check; createMany() specifically tells you to use buildMany().","commonSituations":"Copied a factory usage pattern but forgot to wire the adapter (ApiPersistenceAdapter or KnexPersistenceAdapter); refactored a test from persisted to in-memory data but left a createMany() call; factory was constructed with a null/undefined adapter argument.","solutions":["If you want persisted entities, pass an adapter when constructing the factory (e.g. new ApiPersistenceAdapter({httpClient: page.request, endpoint: '/api/admin/posts/'})).","If you only need in-memory objects, call buildMany(optionsList) instead of createMany(optionsList).","If the adapter is conditionally available, guard the createMany call behind an 'if (factory has adapter)' check.","Run 'pnpm build' after factory changes (per the e2e AGENTS.md) to catch wiring issues."],"exampleFix":"// before: no adapter, persistence impossible\nconst factory = new PostFactory();\nconst posts = await factory.createMany([{status: 'published'}, {status: 'draft'}]);\n\n// after: wire an adapter for persistence\nconst adapter = new ApiPersistenceAdapter({httpClient: page.request, endpoint: `${baseURL}/api/admin/posts/`});\nconst factory = new PostFactory(adapter);\nconst posts = await factory.createMany([{status: 'published'}, {status: 'draft'}]);\n\n// or, for in-memory only, use buildMany:\nconst factory = new PostFactory();\nconst posts = factory.buildMany([{status: 'published'}, {status: 'draft'}]);","handlingStrategy":"validation","validationCode":"import {Factory} from './factory';\n\nfunction assertAdapter(factory) {\n    if (!factory.adapter) {\n        throw new Error(`${factory.constructor.name} has no persistence adapter. Pass one to the constructor, or use buildMany() for in-memory objects.`);\n    }\n}\n\n// Before calling createMany:\nassertAdapter(factory);\nawait factory.createMany(list);","typeGuard":"function hasAdapter(factory) {\n    return factory instanceof Factory && factory.adapter != null;\n}","tryCatchPattern":null,"preventionTips":["Construct factories with an adapter when you need persistence; use a factory helper like createPostFactory(page.request) that wires the adapter for you.","Use build()/buildMany() deliberately when you only need in-memory data.","Run 'pnpm build' after factory changes to catch wiring regressions."],"tags":["e2e","data-factory","typescript","test-infrastructure","configuration"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}