{"record":{"id":"5e1673d1e2df07bb","repo":"TryGhost/Ghost","slug":"entitytype-with-id-id-not-found","errorCode":null,"errorMessage":"${entityType} with id ${id} not found","messagePattern":"(.+?) with id (.+?) not found","errorType":"exception","errorClass":"Error","httpStatus":404,"severity":"error","filePath":"e2e/data-factory/persistence/adapters/api.ts","lineNumber":58,"sourceCode":"        const response = await this.httpClient.post(this.buildUrl(), {\n            data: this.transformRequest(data as unknown as TRequest)\n        });\n\n        if (!response.ok()) {\n            const errorBody = await response.json().catch(() => null);\n            const errorMessage = errorBody ? JSON.stringify(errorBody) : '';\n            throw new Error(`Failed to create ${entityType}: ${response.status()} ${errorMessage}`);\n        }\n\n        const body = await response.json() as TResponse;\n        return this.transformResponse(body) as T;\n    }\n\n    async findById<T>(entityType: string, id: string): Promise<T> {\n        const response = await this.httpClient.get(this.buildUrl(id));\n\n        if (response.status() === 404) {\n            throw new Error(`${entityType} with id ${id} not found`);\n        }\n\n        if (!response.ok()) {\n            throw new Error(`Failed to find ${entityType}: ${response.status()}`);\n        }\n\n        const body = await response.json() as TResponse;\n        return this.transformResponse(body) as T;\n    }\n\n    async update<T>(entityType: string, id: string, data: Partial<T>): Promise<T> {\n        const existing = await this.findById<T>(entityType, id);\n\n        const response = await this.httpClient.put(this.buildUrl(id), {\n            data: this.transformRequest({...existing, ...data} as unknown as TRequest)\n        });\n\n        if (!response.ok()) {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/e2e/data-factory/persistence/adapters/api.ts#L40-L76","documentation":"Thrown by ApiPersistenceAdapter.findById() when the GET to {endpoint}/{id} returns HTTP 404. The entity with that id does not exist at the API. This is distinct from other non-ok statuses (handled by error 94) — a 404 is specifically 'not there', which the adapter surfaces with the entityType and id for easy identification.","triggerScenarios":"A test looks up an entity by id that was never created, was already deleted, or whose id is wrong. Also triggered internally by update() (which calls findById first) when attempting to update a non-existent record.","commonSituations":"Test ordered before the factory.create finished (race); the entity was deleted by a previous test step or another worker; id copied from a different environment; a factory build() generated an id that doesn't correspond to a persisted record (build is in-memory only).","solutions":["Confirm the id came from a successful create() (not a build(), which is in-memory only).","Check whether a prior delete or another worker removed the entity — use per-test isolation if tests interfere.","Verify the endpoint includes the correct resource path (a wrong baseURL/endpoint yields 404 even for valid ids).","If the lookup is optional, catch the error and treat 404 as 'absent' rather than failing the test.","Ensure 'pnpm dev' is serving the correct Ghost instance where the data was created."],"exampleFix":"// before: assumes the post exists, throws on 404\nconst post = await apiAdapter.findById('posts', id);\n\n// after: tolerate absence when the test expects it\nlet post;\ntry {\n    post = await apiAdapter.findById('posts', id);\n} catch (err) {\n    if (/not found/.test(err.message)) post = null;\n    else throw err;\n}","handlingStrategy":"validation","validationCode":"// Guard lookups you expect might miss\nasync function findOrNull(adapter, entityType, id) {\n    try {\n        return await adapter.findById(entityType, id);\n    } catch (err) {\n        if (/not found/.test(err.message)) return null;\n        throw err;\n    }\n}","typeGuard":"function isNotFoundMessage(msg) {\n    return /with id .* not found/i.test(msg);\n}","tryCatchPattern":"try {\n    const entity = await factory.findById(id);\n} catch (err) {\n    if (isNotFoundMessage(err.message)) {\n        // expected absence — handle gracefully\n    } else throw err;\n}","preventionTips":["Only look up ids returned from a successful create().","Use per-test isolation when tests can delete each other's data.","Remember build() is in-memory — its results are not findable via the adapter."],"tags":["e2e","data-factory","api-adapter","not-found","test-infrastructure"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}